Створюємо сервотестер на базі мікроконтролера ATMega
Нещодавно я почав освоювати програмування на базі мікроконтролерів ATmega. Зацікавило, що ці навички можна застосувати і для моделізму.
Після перших експериментів з кнопочками та світлодіодами, захотілося зробити щось корисне та пов’язане з моделізмом. Мій вибір припав на “Сервотестер“. За основу функціоналу сервотестера було взято готовий екземпляр Turnigy Servo Tester.
Як працює серва
Серви, що застосовуються в моделізмі, використовують три дроти для роботи. Дріт для живлення зазвичай від 4.8В до 6В, загальний дріт (земля) і сигнальний дріт. Керуючий сигнал передає інформацію про необхідне положення вихідного валу. Вал пов’язаний із потенціометром, який визначає його положення. Контролер у серві по опору потенціометра і значенням сигналу, що управляє, визначає, в яку сторону потрібно обертати мотор, щоб отримати потрібне положення вихідного валу. Чим вище напруга живлення серви, тим швидше вона працює та більший момент розвиває.
Керуючий сигнал
Керуючий сигнал є імпульсами змінної ширини. Імпульси повторюються із постійною частотою (як правило, із частотою 50Гц). Положення серви визначається шириною імпульсу. Для типової серви, яка використовується в радіокерованих моделях, тривалість імпульсу 1500 мкс означає, що серва повинна зайняти середнє положення. Збільшення або зменшення довжини імпульсу змусить серву повернутися за годинниковою або проти годинникової стрілки відповідно.
Таким чином, для управління сервою нам потрібно формувати ШІМ (PWM) із частотою 50 герц. При цьому для положення “0” тривалість імпульсу повинна становити 1000 мікросекунд, а для положення “максимум” 2000 мікросекунди. Середнє положення – 1500 мікросекунд.
Схема сервотестера
Мій сервотестер працюватиме з двома сервами. На ньому буде три світлодіоди, що відображають режим сервотестера. ШІМ (PWM) буде формуватися за допомогою мікроконтролера ATMega8, а сигнал, що задає, буде формуватися за допомогою потенціометра. Управляючі сигнали для серв формуються на ногах OC1A, OC1B. Режими перемикатимуться кнопкою.
- Режим 1 – положення серв задається потенціометром;
- Режим 2 – задається середнє положення сірв;
- Режим 3 – сигнал, що задає, циклічно змінюється від одного крайнього положення до іншого.
Живлення сервотестора здійснюється від батарей напругою 6-12В.
Друкована плата
Завантажити – файл друкованої плати у форматі *.lay можна завантажити за цим посиланням.
Вихідний код
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
//=================================== АЦП ==================================
//Ініціалізація АЦП:
void adc_init(void){
ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS1) | _BV(ADPS2); // prescaler = 128
}
//Чтение канала АЦП:
uint32_t adc_read(uint8_t ch){
ADMUX = _BV(REFS0) | (ch & 0x1F); // set channel (VREF = VCC)
ADCSRA &= ~_BV(ADIF); // clear hardware "conversion complete" flag
ADCSRA |= _BV(ADSC); // start conversion
while(ADCSRA & _BV(ADSC)); // wait until conversion complete
return ADC; // read ADC (full 10 bits);
}
int main() {
char mode=0; // Режим - за замовчуванням 0
int direct=0;
uint16_t adc_result;
#define ICR_MAX F_CPU/50 // ICR1(TOP) = fclk/(N*f) ; N-Делитель; f-Частота; 1000000/1/50 = 20000
#define OCR_MIN ICR_MAX/20
#define OCR_MAX ICR_MAX/10
#define OCR_CENTER (ICR_MAX/4/10)*3
// На порту кнопки включаємо підтягуючий резистор
DDRB &= ~(1<<4);
PORTB |= (1<<4);
// Налаштовуємо порт світлодіодів
DDRC = (1<<1) | (1<<2) | (1<<3);
PORTC |= (1<<(mode+1));
// Налаштовуємо PWM на таймері 1 (вихід на ногах PB1, PB2)
TCCR1A = 0; // Відключаємо PWM поки конфігуруватимемо
ICR1 = ICR_MAX; // Частота завжди 50 Гц
// Включаємо Fast PWM mode via ICR1 на Таймері 1 без дільника частоти
TCCR1A = (1<<WGM11);
TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);
// Встановлює PB1 та PB2 як вихід
DDRB |= (1<<1) | (1<<2);
// Включаємо PWM на port B1 та B2
TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
// Включаємо АЦП
adc_init();
while(1){
// Якщо кнопка натиснута (Переключення режимів)
if ((PINB & (1<<4)) == 0)
{
// Чекаємо поки кнопку відпустять
while ((PINB & (1<<4)) == 0) {
_delay_ms(200);
}
mode++;
if (mode > 2) {
mode = 0;
}
// Включаємо потрібний світлодіод
PORTC &= ~((1<<1) | (1<<2) | (1<<3));
PORTC |= (1<<(mode+1));
}
switch (mode){
case 0:{
// Задаємо положення сервомеханізму, залежно від положення потенціометра adc_result
adc_result=adc_read(0);
OCR1A = OCR_MIN+(adc_result * (OCR_MAX-OCR_MIN)/1024);
OCR1B = OCR1A;
break;
}
case 1:{
// Задаємо центральне положення серви
direct=0;
OCR1A = OCR_CENTER;
OCR1B = OCR1A;
break;
}
case 2:{
// Циклічна зміна положення серви
if (direct==0){
OCR1A++;
OCR1B++;
if (OCR1A >= OCR_MAX) {
direct=1;
}
}
if (direct==1){
OCR1A--;
OCR1B--;
if (OCR1A <= OCR_MIN) {
direct=0;
}
}
_delay_ms(1);
break;
}
}
}
}
Завантажити – усі ресурси проекту (плата, прошивка, вихідний код).
Фюзи не чіпати! Всі значення за замовчуванням. Кого таки цікавлять значення за замовчуванням, їх легко знайти у пошуку.
І на завершення статті відеоогляд роботи сервотестера:
Хочу висловити велику подяку за допомогу в реалізації проекту Корягину Андрію (створення друкованої плати та оптимізація коду).
13.11.2012 о 19:22
Это все хорошо, а вот частоту или конфиг биты указать забыли
14.11.2012 о 09:52
Все правильно, эти параметры не указывались т.к. проект разрабатывался под стандартные заводские настройки микроконтроллера, что бы не усложнять жизнь новичкам в этом деле. Можете зайти в настройки проекта (AVR Studio) по ссылке “скачать” и сами убедиться в том что все выставлено по умолчанию.
14.11.2012 о 10:05
Так и написали бы – 1 мгц.
14.11.2012 о 12:42
проверил, работает, спасибо
21.12.2012 о 09:28
Здравствуйте,собрали сервотестер.Прошили.
При подключении сервопривод ведет себя неодекватно. Просто дергается из стороны в сторону и все.
Режимы не переключаются.
Помогите пожалуйста. В чем может быть загвоздка. Уже неделю мучаемся.
Заранее спс
22.12.2012 о 10:46
Добрый день! Если не работает, значит что то сделали не так. Причин может быть много. Может зашивается не так как надо из-за программы которой прошиваете (например выставлены какие то параметры которых быть не должно). Все параметры при прошивке данного микроконтроллера должны быть выставлены как заводские (можно почитать мануал по микроконтроллеру). Один из наших читателей сталкивался с проблемой и это было то что частота для микроконтроллера было выставлена не 1 мгц. Настройки можно поглядеть в проекте AVR studio который прилагается к статье.
14.12.2015 о 10:01
Вадим, решили проблему с данным сервотестером?
22.12.2012 о 19:59
Доброго времени суток! Контроллер новый, до этого не программировался, скорее всего с заводскими настройками. Программировал с помощью UniProf. Я прошил только PROGRAM, EEPROM и FUSEы не трогал. Какие настройки должны быть для FUSE, как сменить частоту и надо ли прошивать EEPROM? Сильно не пинайте я полный ноль в этом, но тестер собрать и запустить очень хочется. Заранее благодарю.
22.12.2012 о 23:04
Такой программой прошивальщиком не пользовался и особенностей не знаю. Я для прошивания использовал “eXtreme Burner- AVR” еще пообщавшись с товарищем который много работает с устройствами на микроконтроллерах услышал такую вещь: “80% проблем с тем что не работает нормально схема, плохо пропаян микроконтроллер.” Посмотрите то как запаян микроконтроллер и попробуйте другой программой зашить. Так как я перед своими опытами с микроконтроллерами много программ перепробовал и вывод был один – не все они одинаково полезны)) одна и таже схема зашивалась в микроконтроллер, но с одной программы работала, а с другой нет.
28.10.2014 о 08:36
Здраствуйте! Почему серва отклоняется только на 90 градусов (на видео)?
28.10.2014 о 13:01
Добрый день! Большинство серв имеют ход ~90°, это обусловлено шириной импульса от 1мс до 2мс. В данном случае 1,5мс это центр. Бывают сервы и с большим ходом или расширители для серв которые увеличивают ход сервы (0.8 – 2.2мс). Есть специализированые сервы которые имеют ход 180° или 360° (для специализированых это обычно пишут в описании).
28.10.2014 о 13:41
Спасибо за ответ!
09.11.2014 о 12:22
Дайте картинку с фюзами, один камень уже убил.
10.11.2014 о 13:46
Фюзы трогать не надо. Все значения по умолчанию. Если у Вас какая то за мудреная программа прошивальщик, в поиске можно глянуть для ATMega8 значения по умолчанию для фюз.
12.11.2014 о 14:16
абсолютно случайно нашел у себя еще одну мегу, прошилась, дальше буду собирать.
15.03.2015 о 14:04
Доброго дня, можно ли вместо потенциометра 20к использовать 50к, что для этого нужно поправить в прошивке?
16.03.2015 о 09:38
Доброго! Можно и 50к. В прошивке ничего менять не надо.
22.03.2015 о 21:26
Здраствуйте. Прошивку контроллера производится отдельно без элементов деталей в схеме?
23.03.2015 о 15:20
Добрый день. Прошивку можно и на схеме зашивать.
14.12.2015 о 09:46
Здравствуйте, собрал ваше устройство, но работает оно немного не корректно. При первом включении загорается крайний правый светодиод (как и у вас на видео), в этом режиме сервотестер работает как нужно, при повороте потенциометра сервомашнка крутится так как и должна. Но при попытке переключения режима на какой то другой, крайний правый светодиод так и продолжает гореть, то есть получается что включены 2 режима одновременно, дальнейшее нажатие кнопки включает соответственно крайний левый светодиод, но крайний правый продолжает гореть (опять 2 режима). А при отключенной сервомашинке, устройство работает адекватно, все режимы переключаются (светодиоды загораются). Вопрос, может ли быть проблема в сервоприводе? Пробовал на MG995
15.12.2015 о 11:22
Добрый день. Не совсем понял: у вас все режимы работают как надо, если не обращать внимание на постоянно горящий правый светодиод? Проверите внимательно еще раз схему. То что указано в статье работает корректно, было опробовано не на одном собраном сервотестере.
15.12.2015 о 11:58
нет, режимы работают не так как надо, получается смешение 2 режимов и сервопривод ведет себя некорректно. Устройство работает нормально тольки при первом включении (первом режиме) потенциометром регулируется полностью.
16.12.2015 о 12:49
Есть вероятность, что не правильно выставлены fuse. Могут быть ньюансы, смотря каким софтом прошиваете. По причине фьюзов уже не раз у разных людей проблемы были. Должны быть выставлены стандартные (заводские) настройки фьюзов для этого контроллера.
16.12.2015 о 13:31
После покупки в магазине их не трогал, хорошо обязательно проверю. Прошиваю sinaProg – всегда четко работает. Спасибо за ответ.
25.12.2015 о 18:23
Проблема решилась совершенно случайно, запитал данное устройство через USB порт компьютера и все заработало адекватно! Также проверил работу от батарейки крона, тоже все четко работает. А при подключении к компьютерному блоку питания и к еще одному регулируемому блоку питания устройство продолжает работать некорректно, как я описывал выше. Не знаю в чем может быть проблема.
25.12.2015 о 20:15
Если все по схеме делали, то питание должно быть от 6v до 12v. делалось в расчете чтобы запитать от 2 или 3 баночного аккумулятора, те что чаще всего в ходу у моделистов. Я как то тестировал подключенным к BEC-у у которого возможен выход на 6v. Если питания будет не хватать то будет не корректно работать, если больше то скорей всего сгорит стабилизатор.
28.12.2015 о 11:01
В том то и дело) Проверял стабилизатор, он исправно выдает 5 вольт. Но устройство работает нормально только от батарейки, а от блока питания нет)
17.05.2016 о 06:37
Жаль что ваш код написан не в среде Ардуино. Синтаксис среды мне не привычен.
Что нужно добавить в программу, или можете скомпилить вариант, чтобы при подаче питания:
– 5 секунд устройство выдавало 1000 мс (значение 0)
– 5 секунд значение 1900 (максимальный газ)
– перешла к значению заданному переменным резистором
?
18.05.2016 о 07:51
Если Вам удобней писать под Ардуино и его используете, то сделайте под него. Тем более под него это проще сделать. Сделать можно все, но прибор задумывался как копия по функционалу китайских аналогов.
31.10.2017 о 21:51
а серво реально на 90 отклоняться прога ведать такая
27.05.2019 о 18:12
Спасибо trim! Всё работает, все режимы. Правда не обошлось без косяков, не заметил соплю между левым резистором и ресетом и долго не мог понять почему ничего не светится.
12.08.2021 о 15:10
Ну на микроконтроллере я ожидал дисплей с углом поворота (или %) и микросекундами длительности импульсов… А так схема на 555 таймере будет проще.. Короче, получилось “из пушки по воробьям”… Но все равно статья – это труд. Спасибо.