наброски логики, пока не стабильно, но суть думаю понятна
конфиг
Код:
#define Algo_TimeBased // режим обнаружения минимума регулирования мощности лазера основаный на ожидаемом времени попадания пятна в центр датчика
// экспериментальный, базируется на геометрических размерах датчика и скорости Z 3D принтера
#define TimeBased_wait_center 250 // время в милисекундах за которое пятно перемещается от срабатывания по алгоритму Algo_MaxPix до центра датчика
#define TimeBased_wait_second 5000 // время в милисекундах в течении которого ожидаем второго замера (на молой скорости)
логика
Код:
#if defined(laser_power_pwm_target)
void RefrPowerLaser(uint8_t power)
{
if (power > laser_power_pwm_target && RegPowLaser > 1){
RegPowLaser--;
analogWrite(LASER_VCC_PIN,RegPowLaser);
}
if (power < laser_power_pwm_target && RegPowLaser < 255){
RegPowLaser++;
analogWrite(LASER_VCC_PIN,RegPowLaser);
}
}
#endif
Код:
#if defined(Algo_TimeBased)
unsigned long SensedTime;
byte BasePowLaser;
typedef enum {
START,
WAIT_FIRST,
FIRST_TIMER,
ERR_OUT,
FIRST_SENSED,
WAIT_SECOND,
SECOND_SEARCH,
SECOND_SENSED
}state_machine;
state_machine state=START;
#endif//Algo_TimeBased
//-------------------------------------------------------------------------------------------
#if defined(Algo_TimeBased)
//порегулируем мощность лазера
while( (dataMax = ADNS_read(ADNS_MAX_PIX)) &&
( dataMax > laser_power_pwm_target ||
( dataMax < laser_power_pwm_target && RegPowLaser < 255) ) ){
RefrPowerLaser(dataMax);
delay(2);
}
if (RegPowLaser < 255 ) { // лазер в поле зрения
switch(state){
case START:
PIN_HIGH(LED); // сбросим сигнал срабатывания
// помигаем в знак ожидания работы 255=включить лазер , 0=выключить
analogWrite(LASER_VCC_PIN, 0);
delay(250);
analogWrite(LASER_VCC_PIN, RegPowLaser);
delay(250);
break;
case WAIT_FIRST:
SensedTime=millis(); // начинаем замер времени
state=FIRST_TIMER; // работает таймер
break;
case FIRST_TIMER:
currentTime=millis(); // текущее время
if (currentTime >= (SensedTime + TimeBased_wait_center)){ // время вышло, останавливаемся
PIN_LOW(LED); // сигнал срабатывания
BasePowLaser=RegPowLaser; // запоминаем значение регулировки лазера
SensedTime=currentTime; // начинаем замер времени
state=FIRST_SENSED; // первый подход сработал
}
break;
case FIRST_SENSED:
if (RegPowLaser >= (BasePowLaser + 50)){ // отошли от базового уровня на достаточное расстояние
PIN_HIGH(LED); // отключаем сигнал срабатывания
state=SECOND_SEARCH; // второй этап
}
currentTime=millis(); // текущее время
if (currentTime >= (SensedTime + TimeBased_wait_second)){ // время вышло, повторно не тестировали
state=START; // начинаем цикл по новой
}
break;
case WAIT_SECOND:
SensedTime=millis(); // начинаем замер времени
state=SECOND_SEARCH; // возврат пятна после удаления на первое срабатывание
break;
case SECOND_SEARCH:
if (RegPowLaser <= (BasePowLaser+5)){// подошли близко к базовому уровню : срабатываем
PIN_LOW(LED); // включаем сигнал срабатывания
state=SECOND_SENSED; // второй подход сработал
delay(10);
PIN_HIGH(LED); // отключаем сигнал срабатывания
}
currentTime=millis(); // текущее время
if (currentTime >= (SensedTime + TimeBased_wait_second)){ // время вышло, порог не найден
state=START; // начинаем цикл по новой
}
break;
} // end switch
}else{ // лазер вне поля зрения
switch(state){
case START:
PIN_HIGH(LED); // сбросим сигнал срабатывания
state=WAIT_FIRST; // переходим к ожиданию первого вхождения
break;
case FIRST_TIMER:
PIN_LOW(LED); // сигнал срабатывания
state=START; // пролетели поле зрения, авария!
break;
case FIRST_SENSED:
PIN_HIGH(LED); // отключаем сигнал срабатывания
state=WAIT_SECOND; // было удаление после первого срабатывания
break;
case WAIT_SECOND:
PIN_HIGH(LED); // отключаем сигнал срабатывания
state=SECOND_SEARCH; // возврат пятна после удаления на первое срабатывание
break;
/*
case SECOND_SEARCH:
PIN_LOW(LED); // сигнал срабатывания
state=START; // пролетели поле зрения, авария!
break;
*/
case SECOND_SENSED:
PIN_HIGH(LED); // отключаем сигнал срабатывания
state=START; // цикл замера успешно завершен
break;
} // end switch
}
#endif //Algo_TimeBased
Добавлено спустя 3 минуты 47 секунд:первое срабатывание как 250мс от времени начала уменьшения мощности лазера.
второе при приближении этой мощности к ожидаемому минимуму
Добавлено спустя 1 минуту 51 секунду:я наверное запутал названием переменной laser_power_pwm_target
ее нужно было назвать laser_power_MaxPix_target