Перейти к содержанию

Почему двигатель пищит при ШИМ от Arduino?

Обновлено Редакция GAW

Ядро Arduino в init() настраивает все три таймера ATmega328P с делителем 64. Timer0 работает в режиме быстрого ШИМ, Timer1 и Timer2 — в режиме ШИМ с правильной фазой. Обмотка двигателя получает импульсы с этой частотой, и магнитные силы в ней меняются тоже с этой частотой. Kuphaldt называет два источника слышимого шума трансформатора: магнитострикцию — сердечник слегка меняет длину при намагничивании — и механические силы между обмотками, которые растут с током и заставляют их вибрировать. В двигателе работают те же механизмы: при каждом импульсе ШИМ меняются ток в обмотках и силы, действующие на них и на сердечник, и всё это колеблется с частотой ШИМ. Если она звуковая, мотор пищит.

Какая частота у analogWrite

Выводы UnoТаймерРежим ядраЧастота при 16 МГц (наш расчёт)
5, 6Timer0быстрый ШИМ, делитель 6416 МГц / (64 · 256) ≈ 977 Гц
9, 10Timer1ШИМ с правильной фазой, делитель 6416 МГц / (2 · 64 · 255) ≈ 490 Гц
3, 11Timer2ШИМ с правильной фазой, делитель 64≈ 490 Гц

Обе частоты — сотни герц, то есть самая середина звукового диапазона; чтобы писк ушёл, частоту поднимают на десятки килогерц.

Как получить 25 кГц на выводах 9 и 10

В режиме 10 (табл. 16-4 даташита) Timer1 считает вверх-вниз до значения в ICR1, и частоту задаёт формула раздела 16.9.4:

f=fclk2⋅N⋅TOP=16 МГц2⋅1⋅320=25 кГц.f = \frac{f_\text{clk}}{2 \cdot N \cdot TOP} = \frac{16\ \text{МГц}}{2 \cdot 1 \cdot 320} = 25\ \text{кГц}.
// Timer1 mode 10: phase correct PWM, TOP = ICR1, no prescaler -> 25 kHz on pin 9 (OC1A)
void setup() {
  pinMode(9, OUTPUT);
  TCCR1A = _BV(COM1A1) | _BV(WGM11);  // non-inverting output on OC1A
  TCCR1B = _BV(WGM13) | _BV(CS10);    // WGM13:0 = 1010, clk/1
  ICR1 = 320;                         // TOP
  OCR1A = 160;                        // 50 % duty, valid range 0..320
}

Заполнение теперь задают числом от 0 до 320 в OCR1A (вывод 9) или OCR1B (вывод 10), а не через analogWrite(), которая рассчитана на шкалу до 255. Timer0 не трогаем, поэтому millis() и delay() работают как прежде; но библиотека Servo тоже использует Timer1, и вместе с этим кодом её не применить. Подробно о том, как ядро настраивает таймеры, рассказывает урок «analogWrite изнутри», частоту для других делителей подберёт калькулятор ШИМ Arduino.

Цена высокой частоты — нагрев ключа: каждый фронт стоит энергии, и почему MOSFET в ШИМ греется сильнее, разобрано в ответе «MOSFET греется в ШИМ». Схемы ключей и H-мостов для двигателей — в статье «Управление коллекторным двигателем».

Похожие вопросы

Можно ли просто взять analogWrite на выводах 5 и 6, там же частота выше?

Писк станет выше тоном, но не исчезнет: около 980 Гц — всё ещё середина звукового диапазона. Менять делитель Timer0 ради этих выводов нельзя: на нём работают millis() и delay(), и время в скетче поедет.

Не испортит ли 25 кГц драйвер или транзистор?

Может перегреть. С ростом частоты потери на переключение растут пропорционально ей, особенно если затвор MOSFET заряжается через резистор от вывода Arduino. Перед повышением частоты проверьте предельную частоту ШИМ в даташите драйвера и поставьте драйвер затвора, если ключ греется.

Почему мотор пищит сильнее на малых оборотах?

На малом заполнении ток в обмотке пульсирует сильнее относительно среднего, и магнитные силы меняются резче. Частота писка остаётся частотой ШИМ, меняется только громкость.

Источники

  1. Arduino. ArduinoCore-avr 1.8.8: cores/arduino/wiring.c, функция init() — Timer0 — быстрый ШИМ (WGM01, WGM00) с делителем 64; Timer1 — делитель 64 и 8-битный ШИМ с правильной фазой (WGM10); Timer2 — делитель 64 и ШИМ с правильной фазой (WGM20)
  2. Microchip. ATmega48A/PA/88A/PA/168A/PA/328/P Data Sheet (DS40002061B) — разд. 16.9.4: ШИМ с правильной фазой Timer1, TOP — 0x00FF, 0x01FF, 0x03FF, ICR1 (WGM13:0 = 10) или OCR1A, частота f = f_clk / (2 · N · TOP), разрешение не меньше 2 бит; табл. 16-4: режим 10 — WGM13 = 1, WGM12 = 0, WGM11 = 1, WGM10 = 0, TOP = ICR1
  3. Kuphaldt T. R. Lessons In Electric Circuits, Vol. II — AC, 6th ed. (CC BY) — разд. 9.8 «Practical considerations»: слышимый шум трансформатора — в основном магнитострикция, ферромагнитный сердечник слегка меняет длину при намагничивании и гудит с удвоенной частотой сети; под нагрузкой ток вторичной обмотки создаёт силы отталкивания между обмотками, которые заставляют их вибрировать и тоже дают слышимый шум

Нашли ошибку?