Функция millis() в прерываниях

msaygak
Offline
Зарегистрирован: 05.06.2012

Есть приблизительно такой код:

volatile long start_cycle_prev = millis();
volatile long start_cycle_current = millis();
volatile int angle = 0;
volatile int period=1000;

void setup()
{
pinMode(2, INPUT); // Вход, к фототранзистору
attachInterrupt(0, Ir_sens, RISING); //внешнее прерывание по фронту
};

void Ir_sens()
{

angle = 0;
start_cycle_prev = start_cycle_current;
start_cycle_current = millis();
period = start_cycle_current - start_cycle_prev;
}

void loop()
{

if ( millis() >= (start_cycle_current + period )) // Прошло время полного оборота
{
start_cycle_prev = start_cycle_current;
start_cycle_current = millis();
};

angle = round (( millis() - start_cycle_current ) * 360 / period ); // угол поворота в данный момент

// дальше действия в зависимости от угла
}

 

Назначение таково -- есть колесо, которое вращается с неизвестной скоростью. В точке Х стоит датчик, срабатывающий про полном обороте (фототранзистор, геркон -- не важно). Когда колесо поворачивается на 90 градусов нужно совершить какое-то действие.

Алгоритм таков -- засекаем время по millis(); если срабатывает датчик вычисляем время поворота и используем его как период полного оборота. По смещению времени от посленего срабатывания вычисляем угол поворота.

 

Засада в том, что, похоже, функция millis() внутри прерывания дает некорректный результат.

Так и должно быть? Как сделать лучше?

 

leshak
Offline
Зарегистрирован: 29.09.2011

 А подключен-то фото-транс как? Подтяжка к земле есть? Уверенный что ложных сработок нет?

Строки 24-28 - imho лишние. деалают то же что и обработчик, только в зависимосте от времени. в итоге, у вас как-бы тикает "два датчика" и мешают друг-другу.

Вообщем -выкинуть.

Будет врать пока не произойдет две стработки датчика. Можно просто, при инициализцаии start_cycle_prev, start_cycle_current присвоить им нули (кстати не очень хорошая идея там функции вызывать, для этого setup() предназначен), а потом проверять. Пока оба не станут больше нуля - ничего не делать в loop, скорость пока не известна.