Официальный сайт компании Arduino по адресу arduino.cc
Отслеживание принудительной остановки двигателя(на валу-неодим. магниты, на неподв.части-датчик). Голову ломаю 3 месяц О_о
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Чт, 19/09/2019 - 01:44
Всем привет!
Может подскажет кто из знающих...Суть вот в чем...Программировать кое-как умею. Скетч писал сам.
Но он не работает как надо.
ДАНО: маленький эл.двигатель. На его вал насажены 2 неодимовых плоских магнита(как пропеллер расположены, но плоский пропеллер). Эти магниты пролетают мимо стационарно расположенного цифрового датчика Холла: https://umnyjdomik.ru/ky-003-datchik-holla-na-baze-44e-dlya-arduino.html
ЧТО НУЖНО: Если происходит внешний принудительный тормоз двигателя - ардуино это понимает и отключает двигатель(чтобы не молотил впустую), подождав n-миллисекунд.
Ломаю голову уже 3 месяц. Вроде ерунда- но что то упускаю мелкое и не работает в итоге...
Вот ссылка на скетч:
скетч: https://drive.google.com/file/d/14e9MKG0lfQCbSBs95qdo1yLQFhBYEnoq/view?usp=sharing
P.S. в нем написано, что если есть внешнее торможение двигателя- включить реверс. Но это не суть. Можно или реверс или остановку просто. Суть не в этом-а в том, что не работает корректное чтение датчика. Датчик видится, все читается-но где то в коде я косячу....
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...
внешним прерыванием считывать фронт от датчика и в обработчике сбрасывать таймер. Как только таймер натикает определенное время =>вал остановлен {делай что там нужно}
mu_ssina - если хотите, чтобы кто-то посмотрел ваш скетч - вставте код в сообщение, лезть на гугл-драйв ради помощи неизвестному пацаку - это слишком
Да ещё и распакуй, там 4 каких то скетча, разберись какой нужный, открой... пц
Ок, понял! Кидаю прямо сюда!
Любому совету буду рад!
Итак, как выглядит программа (принтскрин вкладок-чтобы общая суть понятна была, далее будет код):
Код вкладок:
Вкладка "3":
Вкладка "Hall_Sensor":
Вкладка "Motor_B":
Вкладка "Tormoza":
attachInterrupt() + перечитать #3
За совет спасибо! Изучу...
Я просто столько времени уже туплю по другому поводу... Как мне сделать так, чтобы постоянно шло отслеживание состояния датчика холла и в зависимости от этого -что то происходило...Вроде могу, умею-но туплю...
За совет спасибо! Изучу...
Я просто столько времени уже туплю по другому поводу... Как мне сделать так, чтобы постоянно шло отслеживание состояния датчика холла и в зависимости от этого -что то происходило...Вроде могу, умею-но туплю...
Попытайтесь четко сформулировать:
1. Что такое "постоянно".
2. Что такое "отслеживание".
3. Что такое "состояние датчика".
4. Что такое "происходило".
Еще такой вопрос...У меня есть подозрение-что ардуина не успевает обсчитывать код, при довольно больших оборотах электрического мини движка. Может быть такое?
При довольно больших оборотах кто угодно не успеет обсчитать код.
Ну вот, давайте прикинем...Микродвигатель крутится на оборотах...сложно сказать на самом деле на каких. Предполагаю(по показателям из интернета) -в районе 10 000 об/мин.
P.S. сейчас сам написал и сам задумался- а какого черта я не замерил программно до сих пор еще? :-)
Вот такой код-будет ли успевать обсчитываться? По ощущениям не успевает, даже подключение Serial пришлось запустить на скорости 2 000 000(иначе все глючит в мониторе порта-кракозябры):
почитать зачем нужны прерывания и перечитать #7
и перечитать #7
Вот это не понял. Седьмое-это что? Пункт правил, строка в программе и т.д. Не понял вообще!
Ок. догадался-сообщение....отвык от местного стиля общения :-))))
Сейчас бьюсь с этими millis();
Может кто объяснит мне, почему у меня в монитор порта выводит какое то длинное непонятное число, если я делаю так как ниже (написал счетчик оборотов в минуту, чтобы понимать скорость вращения двигателя).
В чем загвоздка:
Вот эта строка, по идее, должна выводить какое то не сильно большое число, которое означает скорость вращения двигателя в минуту( оборотов в минуту), но по факту, выводит какую то чушь...Не могу понять в чем дело-может я что упускаю...Выводится длиннющее число-что не является правдой:
Serial.println (currentMillis3);
Сам код:
В общем, сколько ни бьюсь-не получается...В чем проблема- не пойму...
Должно работать -не работает. В смысле не срабатывает удержание.
скачайте готовую библиотеку частотомера и переводите в обороты. вроде назывались FreqMeasure и FreqCount. Одна для низких частот , другая для высоких. Сами выберете
Спасибо! Неее..Основная проблема, о которой я говорю, - это та старая проблема: не реагирует на удержание вала двигателя....Что только не пробовал. Не могу понять в чем дело! И код переписывал по-разному...Чувствую, -какая то фундаментальная проблема! Что то вроде того, что не успевает обсчитывать и т.д.
Крутиться вал, дватаю его рукой, торможу до нуля. По идее должен выдать в серийный порт: "Удержание!", выключиться и включиться реверс. Хрен там!
Код вот такой -если кто поможет, буду премного благодарен! Какую то фундаментальную ошибку допускаю, чувствую...:
С разными вариациями, то что наверху- переписывыл миллион раз. Не работает...
После строки #67 и #77:
Serial.print("dT: "); Serial.println(currentMillis2-currentMillis);
а где следование рекомендациям #3 ?
датчик повесить на пин 2.
Премного благодарен! Отпишусь позже, что вышло!
там старт и стоп только я перепутал
Тс, тебе атмел три таймера (с вачдогом 4) аппаратных в МК старался, пихал, а ты выдумываешь всякие непотребства.
На предмет ошибок не проверял, но общий смысл должен быть понятен.
Запускаем таймер, по достижении которого поднимаем флаг проверки.
Если было внешнее прерывание(вал вращался), то флаг проверки опускаем. если прошел интервал таймера , а оборота не было поднимаем флаг остановки.
Множители и значения от балды выставлял
Давайте, парни, работайте за других башкой, пока те пиво пьют вместо вас. На ICR overflow еще посадите реверс - вообще волшебно будет.
Долго терпел, но не выдержал.
555 - наше всё:
http://nauchebe.net/2012/08/sxema-indikatora-propadaniya-impulsov-lm555/
Давайте, парни, работайте за других башкой, пока те пиво пьют вместо вас.
я имею в этом практический смысл. У меня опыта маловато, поэтому чтобы его пополнять , я проверяю свои умозаключения с помощью новичков. Типа учусь на реальных задачках.
сегодня начал что то пытаться делать наконец :-)
Вопросы появились по вашему коду..А почему датчик на 2 пин нужно? Могу я оставить его на 12 пине(как сейчас)?
P.S. вопрос снят, прочитал описание attachInterrupt(interrupt, function, mode).
Для MaksVV: Работает! Спасибо огромное!!! Не совсем верно работает -но работает! :-)
Моя принципиальная ошибка была в том, что я не знал про отслеживание прерываний с помощью специального пина и всю голову изломал: если сделаю цикл while скажем-чтобы постоянно следить за прерыванием, - то как программа будет все остальное делать?! Она же будет сидеть в цикле постоянно...В общем всю голову сломал и 3 месяца убил :-)))))
Для Kakmyc: Спасибо за основательный глубокий совет! Но для меня это пока сложновато будет...Решил идти простым путем- мне в эту программу еще много что встроить надо...И внешнее прерывание-это микро кирпичик только. А если я не понимаю всех тонкостей этого кирпичика-мне сложно будет писать все остальное. Но -спасибо!
Это имеется ввиду?
Вроде бы да(насколько я понял по выводу). Но главное не это. Главное-я открыл для себя с вашей помощью attachInterrupt -для меня это реальный прорыв. Думаю, дальше все пойдет как по маслу. Я понял как мне крутить этот параллельный цикл(attachInterrupt -следит за датчиком, параллельно с программой).
датчик повесить на пин 2.
В общем, сейчас протестировал многократно.Никак не мог поначалу понять, что не так...И потом дошло в чем дело: При вращении вала, мимо цифрового датчика Холла много раз в секунду пролетают 2 неодимовых магнита(как я говорил раньше, на вал насажен условно говоря воздушный винт, в каждой лопасти-неодимовый магнит). Так вот: значение LOW-HIGH на датчике МЕНЯЕТСЯ МНОГОКРАТНО В СЕКУНДУ.
А attachInterrupt реагирует на смену значения на датчике: attachInterrupt(0, sensor_impulse, CHANGE).
Таким образом, получается, что attachInterrupt работает неправильно! Я то не понял поначалу-почему в Serial постоянно выводится "Shaft stop" -"Shaft start" - в непрерывном режиме, хотя вал крутится....
Вот такая новая беда...И что с этим можно поделать, на ваш взгляд?
Давайте, парни, работайте за других башкой, пока те пиво пьют вместо вас.
я имею в этом практический смысл. У меня опыта маловато, поэтому чтобы его пополнять , я проверяю свои умозаключения с помощью новичков. Типа учусь на реальных задачках.
Тогда я тебе подмогну: во-первых тебе нужен ATOMIC_BLOCK, во-вторых - достаточно анализировать shaft_state на true/false, а прерывание дёргать только по одному фронту.
А attachInterrupt реагирует на смену значения на датчике: attachInterrupt(0, sensor_impulse, CHANGE).
attachInterrupt лишь присоединяет обработчик к прерыванию. Она не может реагировать на что-либо. Реагирует - та функция, которую Вы присоединили при помощи attachInterrupt.
Таким образом, получается, что attachInterrupt работает неправильно!
Нет, она работает правильно, это Вы не понимаете, как она должна работать.
Вот такая новая беда...И что с этим можно поделать, на ваш взгляд?
Где-то у Вас ошибка: либо в скетче, либо в схеме, либо в конструкции.
Вы понимаете, как работает датчик Холла? Он реагирует на магнитное поле. На любое. В частности, на магнитное поле Земли и на сетевую наводку. Другое дело, что его обвязка должна быть настроена так, чтобы все ненужные влияния отсекать.
Для начала просто посмотрите осциллографом, что у Вас выдает датчик Холла при отсутствии магнитов.
Так вот: значение LOW-HIGH на датчике МЕНЯЕТСЯ МНОГОКРАТНО В СЕКУНДУ.
....
Таким образом, получается, что attachInterrupt работает неправильно! Я то не понял поначалу-почему в Serial постоянно выводится "Shaft stop" -"Shaft start" - в непрерывном режиме, хотя вал крутится....
собственно, вы неправильно поняли , почему некорректно работает. По задумке скетча, когда сигнал на датчике МЕНЯЕТСЯ МНОГОКРАТНО В СЕКУНДУ , каждый раз должен просто сбрасываться таймер на 0. поэтому, когда вал крутится , таймер не может дотикать до конца и переменная статус вала при этом всегда находится в положении true ("вал вращается") . Если импульсы от датчика прекратились, таймер доходит до конца и переменная становится false (вал остановлен).
может у меня есть ошибки в скетче, а может у вас в аппаратной части, из за этого и косяки. Попробуйте последовать рекомендациям #33. еще в строке 4 можно попробовать значение увеличить, например до 1000 (вдруг вы вал медленно просто крутите)
собственно, вы неправильно поняли , почему некорректно работает. По задумке скетча, когда сигнал на датчике МЕНЯЕТСЯ МНОГОКРАТНО В СЕКУНДУ , каждый раз должен просто сбрасываться таймер на 0. поэтому, когда вал крутится , таймер не может дотикать до конца и переменная статус вала при этом всегда находится в положении true ("вал вращается") . Если импульсы от датчика прекратились, таймер доходит до конца и переменная становится false (вал остановлен).
может у меня есть ошибки в скетче, а может у вас в аппаратной части, из за этого и косяки. Попробуйте последовать рекомендациям #33. еще в строке 4 можно попробовать значение увеличить, например до 1000 (вдруг вы вал медленно просто крутите)
Ага..через полчасика начну пробовать...
В общем...Всю голову сломал опять-не работал как надо ваш скетч...Неделю его мучал и так и сяк...И заставил работать как надо только что!!!! :-)
Сделал вот что: урезал код до минимума, чтобы просто пока в Serial писало состояние вала-остановлен или работает. То есть, чтобы докопаться до самой сути-в чем ошибка...
Заработало только вот в таком виде:
Логически(на первый взгляд)-ваше гораздо более верно. Но не работало. А так- сразу заработало! :-)
Вот я и думаю-в чем может быть причина...Дребезг контактов? Или логическая ошибка....Пока вот только что обнаружил работоспособную комбинацию-но не успел проанализировать.
Это временная победа. Будет радовать до тех пор, пока вал побыстрее не закрутится. А потом опять подорожник прикладывать к коду придется.
Ошибка с этой цифре: 9600
Меняйте на как минимум 115200
у меня с 9600 и не работало никогда -я об этом выше писал ;-). Кракозябры в serial-е. Стабильно работает на Serial.begin( 2000000 );
Но на самом деле, мне на serial вообще наплевать-это только на период отладки, чтобы видеть, - что происходит...Финальная программа работу с serial-ом не предусматривает вообще.
так ?
пишет "ошибка компиляции для платы Arduino Nano".
Сейчас попробую поэкспериментировать с тем кодом, который я привел выше. Если все будет ок по результатам тестов-отпишусь сегодня ;-). Но уже то, что я вижу в serial-е - меня безумно радует! Похоже конец моим 4-х почти уже месячным мытарствам!
должно компилироваться, я добавил то две строки. Пробуй еще раз
Компилируется:
Глобальные переменные используют 220 байт (21%) динамической памяти, оставляя 804 байт для локальных переменных. Максимум: 1024 байт.
Arduino Nano v2 (ATmega168)
Полагаю, что этого хватит для прекращения массовых мучений?
В железку не заливал. Основной принцип: как только будет зафиксировано, что lastCatchTime перестал "догонять" millis(), значит прерывания не происходят, а следовательно - вал остановился.
мучений нет, просто есть желание понять заработает ли последний мой код. принципиально то особых отличий нет. Можно ещё такой вариант.
и вообще не понял причём тут скорость вывода в порт. Имхо вообще не должна влиять при адекватной работе скетча
Для MaksVV: Пытался и предыдущий ваш код и последний перед этим постом...Ошибку выдает. Причем, если в чистую вкладку все залить-проблем нет. В мой код вставляю-глючит...Видимо где то, что то пропустил-голова квадратная под вечер, не понимаю уже...
Вот код в целом:
я хз все компилируется. переставил обработчик до сетап, так правильней. Может из за этого . Пробуйте код как есть, и скажите как он работает.
ок...щас малесь передохну и ближе к полуночи еще буду пробовать...
Приветствую! Добрался таки до проб...Сегодня все запускается! :-) Работает ваш код! По крайней мере вот этот-#91 :-)
Сейчас буду пробовать другую часть кода(переделывать ваш)...В случае удержания -подождать маленько и включить реверс (метод Motor_B (2, 1) - запускает по часовой стрелке, Motor_B (2, 2)-против часовой).
P.S. Я заметил, что у меня почему то через какое то время начинает глючить IDE.... Перезапуск видимо нужен. Забываю про это и бьюсь, борюсь с труднообъяснимыми ошибками -а там все просто было...