Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Простое управление коллекторным двигателем с помощью МК

Пт мар 30, 2018 12:30:03

сначала попробовал первый вариант, потом второй
частоты сам поправь под свои нужды
добавил схемку, если протеус файл не откроет
Вложения
upr копия.gif
(25.13 KiB) Скачиваний: 348
upr.zip
(47.54 KiB) Скачиваний: 192

Re: Простое управление коллекторным двигателем с помощью МК

Пт мар 30, 2018 12:56:26

[Я правильно понял, нужно записать так?


Как минимум, так (за логикой что в каком такте делать не следил). Я считаю, что мотор крутится, если стоит хотябы один бит из PD6 и PD7,
если двигатель не крутится - ничего не делаем. Остальные предположения в комметариях.

Код:
ISR (TIMER2_OVF_vect)
{
    static unsigned char takt = 0; // если takt только в этом обработчике, не зачем делать эту переменную глобальной 
    unsigned char a;    // если а используется только в этом обработчике, не зачем делать эту переменную (тем более с таким именем)
    static unsigned char b;    // если b используется только в этом обработчике, не зачем делать эту переменную (тем более с таким именем) глобальной

    if ((PORTD & ((1 << PD6) | (1 << PD7))) ==  0) {
        /* двигатель не крутится -> ничего не делаем */
        takt = 0;
        return;
    }

    /* двигатель крутится -> ждем */
    if (++takt == 25) { /* на 25 тике запоминаем положение енкодера */
        b=TCNT0;
        return;
    }
    if (takt >= 30) {
        /* насколько я понимаю, здесь надо отключить мотор, если приращение енкодера менее 20 */

        a = TCNT0;
        if ((unsigned char)(a - b) < 20) {
            PORTD &= ~((1 << PD6) | (1 << PD7)); // Вы же хотите сбросить два старших бита
            takt = 0; /* отключили мотор, сбросили счетчик тактов */
            return;
        }
        /* Тут надо что-то сдедать, если енкодер продолжает выдавать 20 и более импульсов */
        /* например, перезапускаем ожидание "прекращения импульсов" енкодера */
        b = a;
        takt = 25;
    }
}
Последний раз редактировалось viiv Пт мар 30, 2018 13:33:25, всего редактировалось 1 раз.

Re: Простое управление коллекторным двигателем с помощью МК

Пт мар 30, 2018 20:17:29

Ivanoff-iv, viiv Спасибо, парни! Буду разбираться.

Добавлено after 1 hour 9 minutes 16 seconds:
viv, по вашему коду значения переменным стали присваиваться в 16-тиричной системе счисления, а на этапе сравнения - переменной "а" присваивается значение "("
(см. вложенный скрин) и двигатель, по прошествии 30 тактов - останавливается...
Я ШО то не понимаю видно...

Добавлено after 5 hours 56 minutes 56 seconds:
Ivanoff-iv, viiv Короче, так и не смог разобраться... Можете подсказать, что за значения в переменных?
Вложения
Значение переменных.gif
(37.75 KiB) Скачиваний: 334

Re: Простое управление коллекторным двигателем с помощью МК

Пт мар 30, 2018 22:50:51

Можете подсказать, что за значения в переменных?

нет у мкня пртеуса и никогда не было. попробуй правую кнопку мыши для изменения формата отображения.

Re: Простое управление коллекторным двигателем с помощью МК

Сб мар 31, 2018 02:02:17

Можете подсказать, что за значения в переменных?

нет у мкня пртеуса и никогда не было. попробуй правую кнопку мыши для изменения формата отображения.

Блин, ну это ж так просто - дать рабочий код... Мы В РАЗНЫХ ИЗМЕРЕНИЯХ! Вы считаете математически, с учетом синтаксиса языка Си и особенностей микроконтроллеров. Получаете математически выверенный вариант и заключаете: вот это будет работать... Но я - лузер: пользую прогу протеус и не совсем разбераюсь в Си...
Так вот я, лузер, подставляю Ваш код в протеус и вижу фигу! Пытаюсь разобраться в логике - разбираюсь, но понять почему проблема - не хватает знания языка и синтаксиса...
ВОТ И ПРОШУ ВАС, ЕСЛИ НЕ СЛОЖНО, ДАЙТЕ ВЫВЕРЕННЫЙ ВАРИАНТ, ОТНОСИТЕЛЬНО МОЕЙ ЗАДАЧИ, ВАРИАНТ БЕЗ ПРИМЕРОВ!
Ну давайте попробуем не в Протеусе просимулировать. В Какой программе вам удобнее?

Re: Простое управление коллекторным двигателем с помощью МК

Сб мар 31, 2018 06:02:37

мой прпмер чем не угодил? я его собрал, проверил - работает: ждет некоторое время и начинает замерять частоту, до тех пор, пока та не опустится ниже определённого значения (счетчик сбрасываю не в 0 чтобы следующее измерение начиналось сразу после предыдущего, а не мучило возможно заклинивший мотор ещё 2секунды)
если протеус у тебя мой проект не принимает - я выложил схему, собрать её заново несложно,
если чтото не так с КВАВР проектом - для проверки есть прошивка, а С файл можно даже блокнотом открыть и вкопировкть код себе.

Добавлено after 4 minutes 55 seconds:
это уже не пример а код, который ты можешь скопировать себе в проект с минимальными правками (таймеры настроены как у тебя, переменные с теми же именами)
кстати на счет переменных, мне кажется ты не уделил им должного внимания при объявлении (прикинь их область видимости и сохранность) может ещё в этом дело?

Re: Простое управление коллекторным двигателем с помощью МК

Ср апр 04, 2018 17:08:07

Только появилось пару часов, что бы разобраться.
Суть я понял. Проблема была (правда не вся) в представлении целочисленных типов.
Результат выражения (a-b)<20 в определенный период времени давал результат с отрицательным значением ну и мотор соответственно самопроизвольно останавливался. unsigned char - это значения от 0 до 255. Применяя его к выражению - мы отсекаем все значения с отрицательным знаком и тем самым убираем самопроизвольные остановки мотора.
Рабочий код:
ISR (TIMER2_OVF_vect){
if ((PORTD & ((1 << PD6) | (1 << PD7))) == 0) {takt = 0;return;}else { takt++;}
if (takt == 25) { b=TCNT0;return;}
if (takt == 45) {a = TCNT0; takt = 0;
if ((unsigned char)(a - b) < 20) {PORTD &= ~((1 << PD6) | (1 << PD7)); return;}}}

Просто мне нужно было это доступней объяснить.
Но тут тоже не все так как я планировал, ибо эта схема работает при определенных промежутках между измерением и сравнением, а также зависит от количества оборотов мотора. Я же мечтал о решении на подобии процентного соотношения, не зависящего от ТХ мотора окромя энкодера.
Так же, если мотор работает к примеру в режиме "вперед", нажатие на кнопку "назад" - приводит к его остановке (он не успевает остановится и набрать больше тех самых 20-ти импульсов), а нужно, что бы он начинал крутится в обратную сторону. Нужно будет еще дописать, но это уже ерунда.
Спасибо вам обоим за помощь!
Думаю пока я эту железяку соберу - вопросов еще будет уйма...

Добавлено after 7 minutes 37 seconds:
Так же, если мотор работает к примеру в режиме "вперед", нажатие на кнопку "назад" - приводит к его остановке (он не успевает остановится и набрать больше тех самых 20-ти импульсов), а нужно, что бы он начинал крутится в обратную сторону.

Забыл убрать возврат значения функции (зачем это нужно так и не понял из примера viiv) и проблема с остановкой мотора при нажатии при реверсе направления ушла! Почему так? Как return на это влияет?
Рабочий код:
ISR (TIMER2_OVF_vect){
if ((PORTD & ((1 << PD6) | (1 << PD7))) == 0) {takt = 0;}else { takt++;}
if (takt == 25) { b=TCNT0;}
if (takt == 45) {a = TCNT0; takt = 0;
if ((unsigned char)(a - b) < 21) {PORTD &= ~((1 << PD6) | (1 << PD7));}}}
Ответить