Таймеры Arduino UNO — Часть 4. Применение таймеров для управления сервоприводами
Теория
Почему сервоприводы требуют ШИМ 50 Гц
Стандартные сервоприводы для моделизма управляются импульсами длительностью от 1 мс до 2 мс, повторяющимися каждые 20 мс (частота 50 Гц). Длительность импульса определяет угол поворота:
- 1 мс — минимальное положение (обычно 0°).
- 1,5 мс — среднее положение (90°).
- 2 мс — максимальное положение (180°).
Таймеры микроконтроллера позволяют генерировать такие импульсы с высокой точностью, что особенно важно при управлении несколькими сервоприводами одновременно.
Использование Timer1 для генерации сигнала
На Arduino UNO (ATmega328P) Timer1 — это 16-битный таймер, идеально подходящий для генерации низкочастотного точного сигнала. В режиме Fast PWM или Phase Correct PWM можно установить частоту 50 Гц и регулировать длительность импульса через регистры OCR1A или OCR1B.
Отличие Servo.h от ручной настройки таймера
Библиотека Servo.h упрощает работу с сервоприводами, автоматически настраивая таймер и обеспечивая поддержку нескольких каналов. Однако:
- Она занимает часть ресурсов таймера (обычно Timer1).
- Имеет фиксированную частоту обновления.
- Может конфликтовать с другими задачами, использующими тот же таймер.
Ручная настройка даёт полную свободу, позволяет оптимизировать код и использовать только нужные ресурсы.
Практика
Движение сервопривода без библиотеки Servo.h
void setup() {
pinMode(9, OUTPUT); // OC1A
// Настройка Timer1 для Fast PWM, частота 50 Гц
TCCR1A = (1 << COM1A1) | (1 << WGM11); // Вывод на OC1A, режим Fast PWM (ICR1 — TOP)
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); // Делитель 8
ICR1 = 39999; // 16 МГц / 8 / 50 Гц - 1 = 39999
OCR1A = 3000; // ~1.5 мс (среднее положение)
}
void loop() {
OCR1A = 2000; // Поворот в одну сторону (~1 мс)
delay(1000);
OCR1A = 4000; // Поворот в другую сторону (~2 мс)
delay(1000);
}
Проект: Двухосевой поворотный модуль камеры
В этом проекте мы управляем двумя сервоприводами — по осям X и Y, создавая поворотный механизм для камеры.
void setup() {
pinMode(9, OUTPUT); // OC1A — ось X
pinMode(10, OUTPUT); // OC1B — ось Y
// Настройка Timer1 для Fast PWM, 50 Гц
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
ICR1 = 39999;
OCR1A = 3000; // X в центр
OCR1B = 3000; // Y в центр
}
void loop() {
// Панорамирование
for (int pos = 2000; pos <= 4000; pos += 50) {
OCR1A = pos;
delay(20);
}
for (int pos = 4000; pos >= 2000; pos -= 50) {
OCR1A = pos;
delay(20);
}
// Наклон
for (int pos = 2000; pos <= 4000; pos += 50) {
OCR1B = pos;
delay(20);
}
for (int pos = 4000; pos >= 2000; pos -= 50) {
OCR1B = pos;
delay(20);
}
}
Таким образом, мы получаем плавный и точный контроль над положением камеры без использования дополнительных библиотек, что уменьшает нагрузку на микроконтроллер и улучшает совместимость с другими модулями.





