Почему двигатель пищит при ШИМ от Arduino?
Обновлено Редакция GAW
Ядро Arduino в init() настраивает все три таймера ATmega328P с делителем 64. Timer0 работает в режиме быстрого ШИМ, Timer1 и Timer2 — в режиме ШИМ с правильной фазой. Обмотка двигателя получает импульсы с этой частотой, и магнитные силы в ней меняются тоже с этой частотой. Kuphaldt называет два источника слышимого шума трансформатора: магнитострикцию — сердечник слегка меняет длину при намагничивании — и механические силы между обмотками, которые растут с током и заставляют их вибрировать. В двигателе работают те же механизмы: при каждом импульсе ШИМ меняются ток в обмотках и силы, действующие на них и на сердечник, и всё это колеблется с частотой ШИМ. Если она звуковая, мотор пищит.
Какая частота у analogWrite
| Выводы Uno | Таймер | Режим ядра | Частота при 16 МГц (наш расчёт) |
|---|---|---|---|
| 5, 6 | Timer0 | быстрый ШИМ, делитель 64 | 16 МГц / (64 · 256) ≈ 977 Гц |
| 9, 10 | Timer1 | ШИМ с правильной фазой, делитель 64 | 16 МГц / (2 · 64 · 255) ≈ 490 Гц |
| 3, 11 | Timer2 | ШИМ с правильной фазой, делитель 64 | ≈ 490 Гц |
Обе частоты — сотни герц, то есть самая середина звукового диапазона; чтобы писк ушёл, частоту поднимают на десятки килогерц.
Как получить 25 кГц на выводах 9 и 10
В режиме 10 (табл. 16-4 даташита) Timer1 считает вверх-вниз до значения в ICR1, и частоту задаёт формула раздела 16.9.4:
// 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. Перед повышением частоты проверьте предельную частоту ШИМ в даташите драйвера и поставьте драйвер затвора, если ключ греется.
Почему мотор пищит сильнее на малых оборотах?
На малом заполнении ток в обмотке пульсирует сильнее относительно среднего, и магнитные силы меняются резче. Частота писка остаётся частотой ШИМ, меняется только громкость.
Источники
- Arduino. ArduinoCore-avr 1.8.8: cores/arduino/wiring.c, функция init() — Timer0 — быстрый ШИМ (WGM01, WGM00) с делителем 64; Timer1 — делитель 64 и 8-битный ШИМ с правильной фазой (WGM10); Timer2 — делитель 64 и ШИМ с правильной фазой (WGM20)
- 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
- Kuphaldt T. R. Lessons In Electric Circuits, Vol. II — AC, 6th ed. (CC BY) — разд. 9.8 «Practical considerations»: слышимый шум трансформатора — в основном магнитострикция, ферромагнитный сердечник слегка меняет длину при намагничивании и гудит с удвоенной частотой сети; под нагрузкой ток вторичной обмотки создаёт силы отталкивания между обмотками, которые заставляют их вибрировать и тоже дают слышимый шум
Нашли ошибку?
Смотрите также
- analogWrite и таймерыinit(), три таймера, карта выводов, 490,2 и 976,6 Гц, своя частота
- Частота ШИМ ArduinoЧастоты analogWrite по таймерам, выводы, смена делителя, millis() и tone()
- Почему MOSFET греется в ШИМ, хотя без ШИМ холодный?Потери переключения растут с частотой ШИМ и медленным зарядом затвора
- Управление коллекторным двигателемКлюч и диод, ШИМ, H-мост, реверс, торможение, датчики скорости
- Phase Correct PWMШИМ со счётом вверх и вниз и симметричным импульсом