К сожалению, сейчас нет времени писать подробно и с картинками, сделаю это завтра. Если коротко: изготовил валкодер на ось мотор-редуктора от стеклоподъемника ВАЗ в виде кольца с прорезями по ободу и оптопары. Так как направление вращения определять не нужно (оно известно), оптопару поставил одну. Задача: повернув вал на любой угол (и любое кол-во оборотов) например от кнопок, автоматически возвращать его обратно руководствуясь показаниями валкодера. Задача в теории простая, на практике обозначились проблемы, вал почти никогда не возвращается точно в начальное положение, смещается на несколько зубцов. Причем, не на равное количество, а на случайное. Считывал двумя способами: прерыванием по событию и по таймеру, разницы нет. Анидребезг установил, без него вообще ужас что было. Теперь по датчикам вал возвращается в ноль, а на самом деле нет. Отсюда вопрос: почему так происходит? Почему показания расходятся с действительностью? Где посмотреть, что попробовать, куда покопать?
Эммм. Если в коде уверены - значит, без осциллографа далеко не улететь. Чудес не бывает, и что-то где-то даёт лишний дребезг, кмк.
случайно не такой? У него есть конструктивная особенность - при одинаковом числе оборотов моторчика "туда" и "обратно" число оборотов выходного выла разное. Выяснилось случайно, когда делали подъемный кран на его основе. Разница в пару процентов. Точных значений не помню, но на прогон моторчика в 3000 мс в одну сторону веревка поднималась на 19 см, а на прогон моторчика в 3000 мс в другую сторону веревка опускалась на 18,3 см, Надо вводить поправочный коэффициент для случая "обратно", в самом простом случае - увеличить delay на 7-10% при смене направления.
Кстати, задача весьма не тривиальна. У меня несколько дней ушло на подобное устройство.Решения два- или переделать алгоритм и механику так, чтобыв нужном положении у вас был не максимум, а минимум, и управлять с пидом,или использовать магнит на вале и компас или другой магнетометр на раме, ну и опять же пидом, причем опять сделать схему так,чтобы сигнал был минимален в нужной точке, а еще лучше чтобы сигнал был равен нулю и менял знак при пересечении нужной точки. Ну и пид, возможно с Калманом, без пида бесполезно.
Осциллографом смотрел, дребезг сильный, я его вычислил и убил программно. Теперь показывает реальное число зубцов. Воротник то на выходном валу, по идее какая разница сколько оборотов делает мотор, датчик снимает показания на выходе. То, что скорость в разные скорости разная это факт, но ориентир по положению вала, а не по времени.
Вот я думал поставить один магнит и датчик Холла для вычисления поправок. Потому что при многократном автоматическом движении туда-обратно ошибка накапливается.
Допуски, значит. Где-то есть люфт, на который работает гравитация Выход, видимо, в том, чтобы учитывать этот люфт.
Да нет, люфта там нет, во всяком случае такого на четверть оборота. Грешу на инерцию при остановке, причем в одну сторону. Буду сегодня анализатором смотреть когда синал пришел и когда остановилось. Может быть что еще найду, поделюсь. Заодно выложу картинки.
Вырезал вот такую "шестеренку": Нацепил на вал: Установил оптопару: При скорости 255 (полной) получил вот такую картинку (вторая строка - команда на остановку): Как видим, проскакивает по инерции 6-7 зубов. При скорости 85 (1/3), проскакивает пару: Каждый зуб дребезжит при фронте и спаде импульсами несколько десятков микросекунд, обезвредил из антидребезгом с шагом 2мс, теперь считает правильно. При автоматическом вращении туда-обратно на глаз выглядит правдоподобно: но в реальности при вращении в минус смещается на несколько зубов и потому общий баланс плывет в одну сторону (на каждом цикле смещение складывается) что странно, так как при торможении в обе стороны проскакивает на одинаковое ко-во зубов (проверено), что должно уравнивать дисбаланс. Можно, конечно, внести поправку вручную, что я и сделал, но теоретическая составляющая вопроса меня продолжает волновать.
Скорее не помощь, а информация к размышлению. На днях собрал устройство -- небольшой коллекторный моторчик крутил вал через редуктор ( 100..200 (моторчик) : 1 (вал), точно не подсчитывал, не было необходимости), вал должен был совершить определённое количество оборотов и остановиться, к валу была приспособлена оптопара для подсчёта оборотов, контроль осуществлялся ATmega328P (Искра Мини), оптопара "висела на прерывании", обработчик прерывания отрубал питание мотора (правда использовалась библиотека Arduino -- digitalWrite, digitalRead и т.п. что собственно вносило задержку в управляющие сигналы). Так вот вал останавливался как попало, иногда сразу, иногда делал до 3/4 оборота, но успевал остановиться "до следующего срабатывания оптопары" (т.е. сам моторчик успевал сделать несколько десятков оборотов). Для отладки на LCD дисплей выводил количество подсчитанных оптопарой оборотов -- всё чётко. Основные причины такого поведения -- задержка реакции контроллера (библиотека Arduino) + инерция самого коллекторного моторчика. Питание просто "отрубалось" от моторчика и он продолжал крутиться. Один из способов победить инерцию -- не просто отключить питание, а ещё закоротить контакты самого моторчика, тогда ЭДС в обмотках моторчика должна его остановить.
В моем случае инерция не такая большая, в самом устройстве уже встроен редуктор, скорее всего червячный. Да и работает у меня система не в одну сторону, а туда-сюда, то есть должно как будь то должно суммироваться в ноль. А вообще реакция контроллера, даже с библиотечными digitalWrite исчисляется микросекундами, а шаги зубов миллисекундами , проблемы в этом быть не должно.
Большая не большая, но инерция есть, сами говорили в посте #13, что на максимальной скорости проскакивает 6-7 зубъев (кстати замер делали один или несколько? А то может разброс больше). Далее: судя по картинкам из того же поста #13 реакция контроллера измеряется миллисекундами. Это, если моё предположение, что контроллер подсчитывает спадающие фронты сигнала от оптопары, является верным. При чём задержка реакции на двух картинках разная. Вот и получается задержка реакции контроллера разная + инерция 6-7 (не точно 6, а 6-7, что говорит о том, что по инерции вал будет доворачиваться на разный угол) = невозможность простым подходом решить Вашу задачу Как говорили древние итальянцы -- Sublata causa tollitur effectus. Что бы решить задачу, необходимо как минимум устранить две причины: инерцию -- можно попробовать замыкать контакты двигателя, разное время реакции контроллера -- здесь сложнее.
В моем случае инерция не механическая, у меня в программе скорость меняется плавно, чтоюы не было ударов. Задается нужная скорость и через прерывание по таймеру уменьшается/увеличивается до нужного значения. Потому и проскакивает после команда на остановку.
А таймер-то зачем сюда приплели? Я так понял Вам нужно по нажатию кнопки плавно стартовать и по отпусканию плавно остановиться и при этом запомнить "расстояние", что бы потом можно было вернуться назад (так же с плавным пуском и остановом). Это можно сделать одним прерыванием, на которое вешается валкодер для подсчёта "расстояния" и этот же обработчик будет осуществлять плавный пуск и останов. По хорошему и кнопки нужно бы на своё прерывание повесить, но это уже на любителя. А с таймером помимо тех двух проблем, о которых сообщил ранее, прибавляется ещё одна.
Таймер достался в наследство от роботов. Там направление и скорость меняется ежесекундно и в любых размерах, поэтому без плавности никуда. Не вижу в чем дополнительная проблема от этого способа? Прерываний у 328 достаточно и еще осталось. Счетчик пробовал вешать на прерывание по событию и на прерывание по таймеру с опросом, результаты одинаковые и внешне разницы никакой нет.