Есть проект, для которого необходимо простейшее управление коллекторным моторчиком 12V с энкодером на микроконтроллере: - нажатие кнопки "Вперед" - вращение на полных оборотах, по часовой стрелке, на протяжении 30 сек. И пока поступают импульсы с энкодера; - нажатие кнопки "Назад" - вращение на полных оборотах против часовой стрелки, на протяжении 30 сек. И пока поступают импульсы с энкодера; - если в течении 2 сек. энкодер выдал меньше 50 импульсов (т. е. мотор провернул рычаг до упора) - стоп. Вот и все. Программированием МК я не занимался, язык Си или Ассемблер - не знаю. Строить это на ардуино принципиально не хочу. Решил, что с такой "мега сложной" задачей справлюсь с помощью гугля и своих скромных познаний в элетротехнике, но что то пошло не так... Я разобрался как посчитать импульсы с энкодера таймером ТС1 на МК ATMega8 и остановить двигатель по заданному числу импульсов: сконфигурировал ТС1 на внешний источник тактирования, установил прерывание по совпадению, снимаю импульсы с входа Т1 счетчика, сравниваю с регистром ОСR1A (5000 импульсов) и при совпадении останавливаю двигатель подав лог. "0" на выход OC1A счетчика, который в свою очередь управляет драйвером L298. Но вот как сделать, что бы мотор останавливать при падении импульсов до заданного числа да еще на протяжении заданного времени никак понять не могу. Подскажите кому не лень как в принципе можно решить эту "мега задачу"? Всем откликнувшимся - категорическое Спасибо!
Другим таймером считайте время и если в течении заданного времени нет ни одного импульса, то останавливайте мотор.
Можно пример конструкции на Си? Как посчитать отрезок времени другим таймером я понимаю, но как указать МК сравнивать каждые 2 сек. количество импульсов с заданным и если оно меньше 50 импульсов НА ПРОТЯЖЕНИИ ДВУХ СЕКУНД - останавливать мотор - не пойму....
по прерыванию таймера (скажем 4 раза в секунду) сравниваешь состояние твоего счетного таймера с ячейкой массива на 8 элементов если разница меньше 50 - выключаешь мотор, если больше - записываешь состояние в ячейку и переключаешся на следующую ячейку массива, к этой ячейке он вернётся какраз через 2 сек (только первые 8 замеров всегда считай набравшими 50, это надо чтобы первые 2 секунды выдержать, пока счетчик наполнится). так ходя по кругу счетчик точнее отмерит эти 2 секунды, можно, конечно не заморачиваться и заглядывать в счетчик раз в 2 секунды, но тогда работа мотора в заклиненном состоянии может дойти почти до 4сек (если заклинит в начале цикла измерения, но, уже набрав 50 отсчетов)
Добавлено after 1 minute 33 seconds: чтобы считать импульсы можно один из таймеров настроить в режим счетчика внешних импульсов или используя внешнее прерывание инкрементировать переменную-счетчик программно
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Запоминайте текущее число импульсов в переменной, ждите 2 секунды и сравнивайте текущее число импульсов с тем что ранее было сохранено в переменной. Если значения одинаковы, то новых импульсов не было.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Запоминайте текущее число импульсов в переменной, ждите 2 секунды и сравнивайте текущее число импульсов с тем что ранее было сохранено в переменной. Если значения одинаковы, то новых импульсов не было.
ВО! Спасибо, суть понял! Только мне нужно сравнивать с тем значением что было 2 сек. назад: если оно увеличилось меньше чем на 50 импульсов - стоп, если больше чем на 50 импульсов - продолжать работу 30 сек. или 5000 импульсов. ибо мотор с редуктором и в заклиненном состоянии как нибудь да шевелиться будет, выдавая енкодеру эти самые несколько импульсов. Но это уже простая математика. Пошел искать синтаксис для реализации на Си. Нужно еще разобраться с delay. Я так понимаю он полностью останавливает программу на время задержки. Как правильно "ждать" эти 2 сек. нужно еще разобраться... Так же еще не уяснил как задать время работы 30 сек. Спасибо за помощь!
Может лучше не количество импульсов оценивать, а время между ними? 50 импульсов за 2 секунды - это 40 миллисекунд между передними (или задними) фронтами импульсов. Как время между очередными 2 импульсами превысило 80 миллисекунд - стоп.
Первое, что вы делаете не так -- это обращаетесь в обработчике прерывания к переменным, которые к таким обращениям не предрасположены. Я имею ввиду, что переменные не имеют в объявлении модификатора volatile.
В общем сделал я вот так: ISR (TIMER2_OVF_vect) { a=TCNT0; takt++; if (takt==40) {b=TCNT0;} if (takt==45) {if (b==a){PORTD &= ~(1 << PD6)&&~(1 << PD7);} takt=0;} }
Теперь при заклинивании мотора (рычаг доходит до крайнего положения) идет команда СТОП. Но в проекте мотор с редуктором и при заклинивании его ротор будет делать незначительные движения за счет люфта шестерней редуктора, зазоров соединений с рычага и т. п.. То есть енкодер всегда будет выдавать некое (небольшое) значение даже при заклиненном моторе. Не могу придумать как осуществлять команду СТОП, если количество импульсов на Т0, за промежуток времени (2 сек), не превышает к примеру там 20, 50, 100 (в зависимости от енкодера и частоты вращения мотора). Уже пробовал a-b<20 и т. п. ничего не выходит... Подскажите плз как реализовать.
вот у тебя Т1 ведёт счёт времени настрой Т0 на отсчет временнЫх интервалов (получи прерывание с определённой частотой) в прерывании:
Код:
static unsigned int LastMeas; if ((TCNT1-LastMeas)<50) {Остановка мотора}; LastMeas=TCNT1;
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
вот у тебя Т1 ведёт счёт времени настрой Т0 на отсчет временнЫх интервалов (получи прерывание с определённой частотой) в прерывании:
Код:
static unsigned int LastMeas; if ((TCNT1-LastMeas)<50) {Остановка мотора}; LastMeas=TCNT1;
Так я так и делаю, только у меня T0 считает импульсы энкодера, а Т2 ведет отсчет времени. Полный код: #include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #include <util/delay.h>
volatile int b; volatile int a; volatile int takt = 0; ////////////////////////////////////////////////ПРЕРЫВАНИЯ ПО ТАЙМЕРУ №2///////////////////////////////////////////// ISR (TIMER2_OVF_vect) { a=TCNT0; takt++; if (takt==40) {b=TCNT0;} if (takt==45) {if (b==a){PORTD &= ~(1 << PD6)&&~(1 << PD7);} takt=0;} }
////////Порт В DDRB = 0b00000110; //порты PB1 и PB2 установлены как выход. ////////Порт С DDRC = 0x00; //все порты C установлены как входы. PORTC = 0xFF; //подтягивающие резисторы на входы порта С. ////////Порт D DDRD = 0b11000000;//порт PD6, PD7 установлены как выход.
Вот только если дописать строчку (красным) ISR (TIMER2_OVF_vect) { a=TCNT0; takt++; if (takt==40) {b=TCNT0;} if (takt==45) {if (b==a){PORTD &= ~(1 << PD6)&&~(1 << PD7);}} if (takt==50) {if (a-b<20) {PORTD &= ~(1 << PD6)&&~(1 << PD7);} takt=0;}} } То происходит произвольная, через периоды, остановка мотора...
1) если у тебя на заклиненном моторе может набраться 50 импульсов, то при работе мотора размеров таймера т0 не хватит - он на второй круг пойдёт с описанными тобой последствиями: либо используй Т1 либо сокращай время замера (так, чтобы при остановленном моторе импульса 3 - 4 было за время замера) 2) както странно ты засекаешь импульсы - 40 прерываний ждёшь, потом в течении 10 - замеряешь (точка отсчета засекается на 40 такте, а сравнение на 50м).
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
1) если у тебя на заклиненном моторе может набраться 50 импульсов, то при работе мотора размеров таймера т0 не хватит - он на второй круг пойдёт с описанными тобой последствиями: либо используй Т1 либо сокращай время замера (так, чтобы при остановленном моторе импульса 3 - 4 было за время замера) 2) както странно ты засекаешь импульсы - 40 прерываний ждёшь, потом в течении 10 - замеряешь (точка отсчета засекается на 40 такте, а сравнение на 50м).
1. Точно так же ведет себя, если поставить и 10 импульсов и 5... Все зависит от частоты вращения мотора и скорости переполнения Т0. Я так понимаю, что здесь нужно математически высчитывать, или, скорее всего использовать другой подход. 2. Если проводить сравнение на 40 такте, то там же происходит запись значения из TCNT0 в переменную b и в этот же момент , будет происходить прерывание, так как на 40 такте значения а и b будут равны.
2) Т0 умеет считать только до 255, а Т1 и 65000 выдержит (есть разница? ) так что если есть возможность перейти на Т1 - это лучше сделать 3) померь частоту на энкодере работающего мотора чтобы знать, с какими скоростями имеем дело. 4) ты точно знаешь что все переменные у тебя понимаются как беззнаковые? а то при копировании при разных типах можно получить ерунду (и потом махать ею ) если используешь Т0, то сделай переменные а и b типа char.
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
2) Т0 умеет считать только до 255, а Т1 и 65000 выдержит (есть разница? ) так что если есть возможность перейти на Т1 - это лучше сделать 3) померь частоту на энкодере работающего мотора чтобы знать, с какими скоростями имеем дело. 4) ты точно знаешь что все переменные у тебя понимаются как беззнаковые? а то при копировании при разных типах можно получить ерунду (и потом махать ею ) если используешь Т0, то сделай переменные а и b типа char.
1. Они не бездействуют, это время задержки (1-2 сек) которую нужно выждать, перед отключением мотора. Алгоритм: сразу передаем значение TCNT0 переменной a; ждем 40 тактов (1-2 сек) - передаем значение TCNT0 переменной b (делаем это каждые 40 тактов); ждем еще 5 тактов и сравниваем переменные a и b - если равны - СТОП. Так вот если не ждать эти 5 доп. тактов, то при сравнении а будет всегда равняться b. Пять доп тактов это время сравнения, 40 тактов это время задержки между сравнениями. Твой пример не работает по этой причине. 2. Знаю про 8 битные и 16 битные таймеры. Но, если честно, не вижу разницы какой применять касательно данного примера. В проекте еще предусмотрен цикличный таймер c , LSD с меню, Bluetooth и ИК управление. Поэтому 16 битный таймер еще будет нужен. Правда можно взять другой МК. 3. Мотор будет примерно такой: https://ru.aliexpress.com/item/Best-Pri ... 2747006160 Выдавить из китайцев точную инфу по нему пока что сложно, на данном этапе мне это и не нужно. Я хочу изначально разобраться с принципом, что бы наработанный результат можно было применить потом к любому мотору с незначительными правками. В среднем, скорость вращения ротора мотора будет где то 2500 - 3500 об\мин. За оборот энкодер выдает порядка 20-50 импульсов. 4. Ок. Решения пока не нашел...
ISR (TIMER2_OVF_vect) { takt++; if (takt==40) {b=TCNT0;} if (takt==50) { a=TCNT0; if (a-b<20) {PORTD &= ~(1 << PD6)&&~(1 << PD7);} b=a; takt=40; } }
ждет 40 тактов, берёт первую пробу, ещё через 10 берет вторую и сравнивает, следующее сравнение будет через 10 тактов при запуске двигателя не забудь скинуть takt=0; чтобы обеспечить твои обязательные 2 секунды работы двигателя.
Добавлено after 7 minutes 11 seconds: по приблизительным подсчетам при тактовой 8 МГц при рабочих оборотах переполнение Т0 может произойти уже на 3х тактах (а при меньшей тактовой частоте и раньше), поэтому вместо (takt==50) надо писать (takt==42)
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Сейчас этот форум просматривают: Сталкер84 и гости: 31
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения