Функция millis() в прерываниях
- Войдите на сайт для отправки комментариев
Втр, 05/06/2012 - 19:31
Есть приблизительно такой код:
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() внутри прерывания дает некорректный результат.
Так и должно быть? Как сделать лучше?
А подключен-то фото-транс как? Подтяжка к земле есть? Уверенный что ложных сработок нет?
Строки 24-28 - imho лишние. деалают то же что и обработчик, только в зависимосте от времени. в итоге, у вас как-бы тикает "два датчика" и мешают друг-другу.
Вообщем -выкинуть.
Будет врать пока не произойдет две стработки датчика. Можно просто, при инициализцаии start_cycle_prev, start_cycle_current присвоить им нули (кстати не очень хорошая идея там функции вызывать, для этого setup() предназначен), а потом проверять. Пока оба не станут больше нуля - ничего не делать в loop, скорость пока не известна.