Создаем сервотестер на базе микроконтроллера ATMega

Совершенно недавно я начал осваивать программирование на базе микроконтроллеров ATmega. Заинтересовало, то что эти навыки можно применить и для моделизма.

После первых экспериментов с кнопочками и светодиодами, захотелось сделать что то полезное и связанное с моделизмом. Мой выбор пал на «Сервотестер» . За основу функционала сервотестера был взят готовый экземпляр Turnigy Servo Tester.

Как работает сервомашинка

Сервомашинки применяемые в моделизме используют три провода для работы. Провод для питания, обычно от 4.8В до 6В, общий провод (земля) и сигнальный провод. Управляющий сигнал передает информацию о требуемом положении выходного вала. Вал связан с потенциометром, который определяет его положение. Контроллер в сервомашинке по сопротивлению потенциометра и значению управляющего сигнала определяет, в какую сторону требуется вращать мотор, чтобы получить нужное положение выходного вала. Чем выше напряжение питания сервомашинки, тем быстрее она работает и больший момент развивает.

Управляющий сигнал

Управляющий сигнал представляет собой импульсы переменной ширины. Импульсы повторяются с постоянной частотой (как правило, с частотой 50Гц). Положение сервомашинки определяется шириной импульса. Для типичной сервомашинки, используемой в радиоуправляемых моделях, длительность импульса в 1500 мкс означает, что сервомашинка должена занять среднее положение. Увеличение или уменьшение длины импульса заставит сервомашинку повернуться по часовой или против часовой стрелке, соответственно.

Таким образом, для управления сервомашинкой нам потребуется формировать ШИМ с частотой 50 герц. При этом для положения «0 » длительность импульса должна составлять 1000 микросекунд, а для положения «максимум» 2000 микросекунды. Среднее положение — 1500 микросекунд.

Схема сервотестера

Мой сервотестер будет работать с двумя сервомашинками. На нем будет три светодиода отображающих режим сервотестера. ШИМ будет формироваться с помощью микроконтроллера 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;
             }
        }
    }
}

Скачать — все ресурсы проекта (плата, прошивка, исходный код).

Фюзы не трогать! Все значения по умолчанию. Кого все таки интересуют значения по умолчанию, то их легко найти в поиске.

И в завершении статьи видеообзор работы сервотестера:

Хочу выразить большую благодарность за помощь в реализации проекта Корягину Андрею (создание печатной платы и оптимизация кода).

29 комментариев на “Создаем сервотестер на базе микроконтроллера ATMega”

  • Алексей
    13.11.2012 at 19:22

    Это все хорошо, а вот частоту или конфиг биты указать забыли

    • Все правильно, эти параметры не указывались т.к. проект разрабатывался под стандартные заводские настройки микроконтроллера, что бы не усложнять жизнь новичкам в этом деле. Можете зайти в настройки проекта (AVR Studio) по ссылке «скачать» и сами убедиться в том что все выставлено по умолчанию.

  • Алексей
    14.11.2012 at 12:42

    проверил, работает, спасибо

  • Вадим
    21.12.2012 at 09:28

    Здравствуйте,собрали сервотестер.Прошили.
    При подключении сервопривод ведет себя неодекватно. Просто дергается из стороны в сторону и все.
    Режимы не переключаются.
    Помогите пожалуйста. В чем может быть загвоздка. Уже неделю мучаемся.
    Заранее спс

    • Добрый день! Если не работает, значит что то сделали не так. Причин может быть много. Может зашивается не так как надо из-за программы которой прошиваете (например выставлены какие то параметры которых быть не должно). Все параметры при прошивке данного микроконтроллера должны быть выставлены как заводские (можно почитать мануал по микроконтроллеру). Один из наших читателей сталкивался с проблемой и это было то что частота для микроконтроллера было выставлена не 1 мгц. Настройки можно поглядеть в проекте AVR studio который прилагается к статье.

    • Александр
      14.12.2015 at 10:01

      Вадим, решили проблему с данным сервотестером?

  • Ввдим
    22.12.2012 at 19:59

    Доброго времени суток! Контроллер новый, до этого не программировался, скорее всего с заводскими настройками. Программировал с помощью UniProf. Я прошил только PROGRAM, EEPROM и FUSEы не трогал. Какие настройки должны быть для FUSE, как сменить частоту и надо ли прошивать EEPROM? Сильно не пинайте я полный ноль в этом, но тестер собрать и запустить очень хочется. Заранее благодарю.

    • Такой программой прошивальщиком не пользовался и особенностей не знаю. Я для прошивания использовал «eXtreme Burner- AVR» еще пообщавшись с товарищем который много работает с устройствами на микроконтроллерах услышал такую вещь: «80% проблем с тем что не работает нормально схема, плохо пропаян микроконтроллер.» Посмотрите то как запаян микроконтроллер и попробуйте другой программой зашить. Так как я перед своими опытами с микроконтроллерами много программ перепробовал и вывод был один — не все они одинаково полезны)) одна и таже схема зашивалась в микроконтроллер, но с одной программы работала, а с другой нет.

  • Сергей
    28.10.2014 at 08:36

    Здраствуйте! Почему серва отклоняется только на 90 градусов (на видео)?

    • Добрый день! Большинство серв имеют ход ~90°, это обусловлено шириной импульса от 1мс до 2мс. В данном случае 1,5мс это центр. Бывают сервы и с большим ходом или расширители для серв которые увеличивают ход сервы (0.8 — 2.2мс). Есть специализированые сервы которые имеют ход 180° или 360° (для специализированых это обычно пишут в описании).

  • Сергей
    09.11.2014 at 12:22

    Дайте картинку с фюзами, один камень уже убил.

    • Фюзы трогать не надо. Все значения по умолчанию. Если у Вас какая то за мудреная программа прошивальщик, в поиске можно глянуть для ATMega8 значения по умолчанию для фюз.

      • Сергей
        12.11.2014 at 14:16

        абсолютно случайно нашел у себя еще одну мегу, прошилась, дальше буду собирать.

  • Денис
    15.03.2015 at 14:04

    Доброго дня, можно ли вместо потенциометра 20к использовать 50к, что для этого нужно поправить в прошивке?

  • Здраствуйте. Прошивку контроллера производится отдельно без элементов деталей в схеме?

  • Александр
    14.12.2015 at 09:46

    Здравствуйте, собрал ваше устройство, но работает оно немного не корректно. При первом включении загорается крайний правый светодиод (как и у вас на видео), в этом режиме сервотестер работает как нужно, при повороте потенциометра сервомашнка крутится так как и должна. Но при попытке переключения режима на какой то другой, крайний правый светодиод так и продолжает гореть, то есть получается что включены 2 режима одновременно, дальнейшее нажатие кнопки включает соответственно крайний левый светодиод, но крайний правый продолжает гореть (опять 2 режима). А при отключенной сервомашинке, устройство работает адекватно, все режимы переключаются (светодиоды загораются). Вопрос, может ли быть проблема в сервоприводе? Пробовал на MG995

    • Добрый день. Не совсем понял: у вас все режимы работают как надо, если не обращать внимание на постоянно горящий правый светодиод? Проверите внимательно еще раз схему. То что указано в статье работает корректно, было опробовано не на одном собраном сервотестере.

      • Александр
        15.12.2015 at 11:58

        нет, режимы работают не так как надо, получается смешение 2 режимов и сервопривод ведет себя некорректно. Устройство работает нормально тольки при первом включении (первом режиме) потенциометром регулируется полностью.

        • Есть вероятность, что не правильно выставлены fuse. Могут быть ньюансы, смотря каким софтом прошиваете. По причине фьюзов уже не раз у разных людей проблемы были. Должны быть выставлены стандартные (заводские) настройки фьюзов для этого контроллера.

          • Александр
            16.12.2015 at 13:31

            После покупки в магазине их не трогал, хорошо обязательно проверю. Прошиваю sinaProg — всегда четко работает. Спасибо за ответ.

          • Александр
            25.12.2015 at 18:23

            Проблема решилась совершенно случайно, запитал данное устройство через USB порт компьютера и все заработало адекватно! Также проверил работу от батарейки крона, тоже все четко работает. А при подключении к компьютерному блоку питания и к еще одному регулируемому блоку питания устройство продолжает работать некорректно, как я описывал выше. Не знаю в чем может быть проблема.

          • Если все по схеме делали, то питание должно быть от 6v до 12v. делалось в расчете чтобы запитать от 2 или 3 баночного аккумулятора, те что чаще всего в ходу у моделистов. Я как то тестировал подключенным к BEC-у у которого возможен выход на 6v. Если питания будет не хватать то будет не корректно работать, если больше то скорей всего сгорит стабилизатор.

          • Александр
            28.12.2015 at 11:01

            В том то и дело) Проверял стабилизатор, он исправно выдает 5 вольт. Но устройство работает нормально только от батарейки, а от блока питания нет)

  • Жаль что ваш код написан не в среде Ардуино. Синтаксис среды мне не привычен.

    Что нужно добавить в программу, или можете скомпилить вариант, чтобы при подаче питания:
    — 5 секунд устройство выдавало 1000 мс (значение 0)
    — 5 секунд значение 1900 (максимальный газ)
    — перешла к значению заданному переменным резистором
    ?

    • Если Вам удобней писать под Ардуино и его используете, то сделайте под него. Тем более под него это проще сделать. Сделать можно все, но прибор задумывался как копия по функционалу китайских аналогов.

Оставить комментарий