Прерывание по таймеру и ШИМ

Имеется атмега328р


К которой подключены:
Серва 1 к D5
Серва 2 к D6
Шаговый драйвер (dir, step, en, к D12, D8, D10)
Индикатор к D13 и D2

Также используется прерывание по таймеру 2 канал B, который задействует d11(судя по таблице)

Нужен ШИМ , который планировался на D9.
Но там ШИМ не работает.
Без прерывания работает.

Как решить проблему?

Для начала выложить полный скетч и схему подключений. Без них я, например, не вижу с какого это бодуна у Вас на девятом пине шим не работает.

1 лайк

Нашел причину.

Используемая библиотека для плавного движения серв ServoSmooth v3.8 использует свой таймер который заглючивает ШИМ

Сейчас ищу как обойти препятствие.

Библиотека использует программный таймер, а ШИМ - аппаратный. Они никак не пересекаются.

Хотя с учетом того, что это библиотека Гайвера - может быть что угодно :slight_smile:

Тем не менее, советую еще раз проверить, в чем причина - думаю насчет причины глюков вы ошибаетесь

ServoSmooth это надстройка над “стандартной” библиотекой Servo.h и для плат на 328p они работают на Timer1 Поэтому оба вывода Timer1 становятся недоступны для ШИМ. Подключать серво можно к любым выводам. Поэтому если вы перенесете их на другие пины с D5 и D6, то у вас будет два ШИМ канала Timer0. Но на нем считается millis и delay, поэтому частоту ШИМ менять нельзя, только скважность (0 - 255).

Как только включаю в код строчки

servo1.attach(6, 0);
servo2.attach(5, 100);

то ШИМ на любых доступных ногах перестает работать.

Если эти строчки убрать из кода, то все работает на любых доступных ногах
9,10,11

опа… где?
ничего такого в коде не вижу, вроде все написано на миллис-микрос

уппс… слепой.

@Veter753
игнорируйте мои сообщения выше, @Upper прав

Вы пришли сюда поговорим “сам с собою”?

Вам не кажется, что мы видели Вашего кода и понятия не имеем, что там за библиотеки у Вас, как используются, о чём всё это вообще.

Пока не выложите скетч и схему, так и будете сам с собой разговаривать.

Спасибо, проблема в принципе решена именно по вашему совету.
Но отсутствие возможности увеличить частоту ШИМ огорчает.

Евгений, Ваше первое сообщение мне помогло.
Понял, что нужно искать и отсекать иное нежели таймеру 2 как причину.

Сейчас появился иной вопрос.

Имеет ли смысл на пинах D5, D6 поднимать частоту ШИМ с правкой делителя miles, micros,…?
Вот по этому примеру:

Если очень хочется или очень нужен разогнанный ШИМ на системном (нулевом) таймере без потери функций времени, то можно их скорректировать следующим образом:

#define micros() (micros() >> CORRECT_CLOCK)

#define millis() (millis() >> CORRECT_CLOCK)

void fixDelay(uint32_t ms) {

delay(ms << CORRECT_CLOCK);

}

На мой взгляд, менять частоту Таймера0 можно, если быть уверенным на что и как это может повлиять. Библиотеки могут использовать millis и micros и надо разобраться с их работой.
Наверно зависит от условий.
Действительно ли необходимо иметь частоту ШИМ > 1 КГц, и если да то на скольких выводах, в каких пределах и с какой точностью.
Можно ли перенести задачу с таймера 2 на таймер 0 и тогда реализовать шим на таймере 2 (если его точности достаточно).
Можно ли использовать другой МК, в котором не будет ограничений.

Какой алгоритм сейчас выполняет таймер2 в вашей программе?

Тики шаговика и двух серв в прерывании по таймеру

Точность не нужна, но задействовать таймер0 не рекомендуют.

Вот как раз задумался о переходе на lgt8. Там и шимов больше и таймеров. И частота выше, что для парсинга данных + шаговик+2 сервы+датчик давления и его индикация совсем не лишним будет.

Один моторчик через мосфет чтобы не пищал. Точность не нужна. Регулировка от 0 до 255 хватит с точностью ±20

Если программировать умеете, то ПРОБЛЕМ с переносом на Таймер0 может не быть. Насколько я помню у Гайвера, в шаговике предлагается использовать прерывание по OCR2A. В этом случае алгоритм не сложно перенести на OCR0A без изменения частоты Таймера 0. Зачем тики на прерываниях для серв, не помню, но если нужны, то посмотреть, возможно ли сделать аналогично.

Я спрашивал про частоту ШИМ. Т.к. На 8 битном таймере 2 при разрешении 0 - 255, частота может меняться только шагами 64 32 8 1 … КГц.

Если вам все равно на каком МК делать, то сейчас в Arduino IDE доступны и другие архитектуры RP2040 ESP32 STM с хорошей документацией. lgt8 - сильно похож на 328р, но принципиальные различия тоже есть, а документация не очень понятная.

Дополнение. А может проще по трудозатратам добавить еще одну NANO.

Не умею.
Умею лепить из разных чужих кусков кода с пониманием того что делаю % на 80 методом тыка.

Без них сервы работают не плавно.
Использую плавный пуск, ускорение и торможение сервомоторов.
С тиками все работает ровно и плавно.

Не все равно. Для ардуино куча библиотек и примеров, откуда можно взять нужные куски.

Для других этого ничего нет либо трудно найти.
От этого и отталкиваюсь в вопросе выбора мк.

Если вы используете ServoSmooth, то я так и не понял, зачем Таймер2 для тиков серв? Можете показать пример, как вы работаете с серво ?

И если не хотите смотреть в сторону других архитектур МК, то MEGA 2560 в компактном исполнении стоит ~ 1000 руб.

Можно перевесить ваши тики с таймера2 на таймер0. Поженить ваши прерывания с миллис будет проще, чем ликвидировать последствия изменения частоты ШИМ на таймер0