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

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


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

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

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

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

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

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

Используемая библиотека для плавного движения серв 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