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

Имеется атмега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 в вашей программе?