Специальные цены   новые товары
Закрытая тема
Показано с 1 по 23 из 23

РРМ индикатор

Тема раздела Самодельная электроника, компьютерные программы в категории Общие вопросы; Хочу сделать РРМ индикатор с тестером серво машинок. На данный момент я стою в самом начале изучения AVRов. Принцип работы ...

  1. #1

    Регистрация
    16.06.2008
    Адрес
    Israel (Byalik)
    Возраст
    46
    Сообщений
    134

    РРМ индикатор

    Хочу сделать РРМ индикатор с тестером серво машинок.
    На данный момент я стою в самом начале изучения AVRов.
    Принцип работы самого индикатора представляю себе так.
    PPM с приёмника подаю на ножку INT0 прерывание срабатывает при любом изменение на входе.
    Таймер подщитывает длину импульса и если длина в приделе от 1-2ms выводим результат на LCD в ms
    или в градусах поворота серво машинки.
    Проблемма на данный момент в конфигурации таймера и фюзов.
    Вот тут вариант схемки:
    Миниатюры Миниатюры Нажмите на изображение для увеличения
Название: Servo.jpg‎
Просмотров: 208
Размер:	34.0 Кб
ID:	307175  

  2.  
  3. #2
    Давно не был
    Регистрация
    22.01.2009
    Адрес
    Новочек
    Возраст
    41
    Сообщений
    404
    Вчем конкретно проблемма? Таймер не считает или инт0 не отрабатывает?

  4. #3

    Регистрация
    16.06.2008
    Адрес
    Israel (Byalik)
    Возраст
    46
    Сообщений
    134
    Цитата Сообщение от serg111 Посмотреть сообщение
    Вчем конкретно проблемма? Таймер не считает или инт0 не отрабатывает?
    Таймер считает, но результат каждый раз разный, такое впечатление, что он живёт своей жизнью, не обращая внимание на INT0.

  5. #4

    Регистрация
    19.07.2005
    Адрес
    Москва
    Возраст
    59
    Сообщений
    6,063
    Хм.. конкретнее алгоритм, что и как считаете, зачем любое изменение на входе, а не конкретный фронт, какой таймер пользуете, установки таймера, почему на INT0, а не на ICP1, если хотите работающую вещь получить ставьте кварц.

  6.  
  7. #5

    Регистрация
    28.07.2004
    Адрес
    Москва
    Возраст
    51
    Сообщений
    806
    Цитата Сообщение от Mishanya Посмотреть сообщение
    Таймер считает, но результат каждый раз разный
    Так и есть, таймер выдаёт лишь текущее значение "своего" времени. Надо считать значение по восходящему фронту INT, а затем вычесть его из значения, считанного по падающему фронту. Разность и будет длительностью импульса. Ещё можно по возрастающему фронту обнулить таймер, тогда на прерывании по спаду он будет содержать уже правильное значение PPM. Думайте, пишите, Вы идёте в правильном направлении!
    Бывает, что прерывание INT временно заблокировано другим, а таймер продолжает считать. К моменту разблокировки он будет содержать ошибку времени ожидания. Для борьбы с такой неприятностью AVR содержит механизм захвата внешнего ШИМ. При событии на ноге ICP, текущее значение таймера сохраняется в регистре ICR и выставляется флаг запроса прерывания. В документации всё подробно описано.

  8. #6

    Регистрация
    16.06.2008
    Адрес
    Israel (Byalik)
    Возраст
    46
    Сообщений
    134
    Цитата Сообщение от Boroda Посмотреть сообщение
    Так и есть, таймер выдаёт лишь текущее значение "своего" времени. Надо считать значение по восходящему фронту INT, а затем вычесть его из значения, считанного по падающему фронту. Разность и будет длительностью импульса. Ещё можно по возрастающему фронту обнулить таймер, тогда на прерывании по спаду он будет содержать уже правильное значение PPM.
    Как мне в одном прирывании отличить возрастающий фронт, от спадающего?
    Цитата Сообщение от PigTail
    какой таймер пользуете, установки таймера, почему на INT0, а не на ICP1, если хотите работающую вещь получить ставьте кварц.
    Какой таймер лучше для моей цели 16 или 8 битный (сейчас пользую timer0 8bit).
    ICP1 занят под LCD_RS, кварц нет проблем, поставлю.

  9. #7
    Учит правила
    Регистрация
    15.05.2009
    Адрес
    Москва
    Возраст
    54
    Сообщений
    1,672
    Цитата Сообщение от Boroda Посмотреть сообщение
    AVR содержит механизм захвата внешнего ШИМ
    Как эта штука называется в даташитах? Чтобы поиском в даташите найти...

  10.  
  11. #8
    Забанен
    Регистрация
    02.01.2008
    Адрес
    Москва, ЗАО
    Возраст
    49
    Сообщений
    208
    16-битный таймер, кварца для Ваших целей не надо, фузы ставить под внутрений генератор на 8 мгц, таймер тактировать 1000 кгц. 1тик=1 микросекунда. Из-за двухбайтовой арифметики таймер можно не сбрасывать, а просто вычислять duration=timer-old_timer; (переменные int)

  12. #9

    Регистрация
    28.07.2004
    Адрес
    Москва
    Возраст
    51
    Сообщений
    806
    Цитата Сообщение от Mishanya Посмотреть сообщение
    Как мне в одном прирывании отличить возрастающий фронт, от спадающего?
    Прочитать значение PIND.2 (INT0)

    Цитата Сообщение от EagleB3 Посмотреть сообщение
    Как эта штука называется в даташитах? Чтобы поиском в даташите найти...
    Input Capture Unit

  13. #10
    VRV
    VRV вне форума

    Регистрация
    25.09.2009
    Адрес
    Sevastopol
    Возраст
    41
    Сообщений
    75
    скажу пару слов:
    даже если с таймером разберетесь и он правилоьно определит длительность каналов- показания всеравно будут прыгать, т.к в пачке идет 6-8 импульсов, соответствующих каждому каналу. Т.о. примерный алгоритм следующий:
    1- найти синхроимпульс, длительность которого больше 2.5 мс(у отдельных передатчиков на канал может идти больше 2 мс)
    2-начать измерение длительности импулсов, до седующего синхро. данные измерения писать в массив,
    3- вывести значения длительности для выбранного канала.

    Сама програма расчета(не считая сервиса вывода на жки) займет от силы 10-20 строк и уместится в обработчике прерывания.
    Для отладки попробуйте симуляцию в протеусе(отлов ошибок, да и жки тоже отладить можно)

  14. #11
    Учит правила
    Регистрация
    15.05.2009
    Адрес
    Москва
    Возраст
    54
    Сообщений
    1,672
    Цитата Сообщение от Mishanya Посмотреть сообщение
    Хочу сделать РРМ индикатор с тестером серво машинок.
    На данный момент я стою в самом начале изучения AVRов.
    Загляни сюда. Исходники там есть, а превратить декодер в сервотестер, КМК, задачка в самый раз для начинающего.

  15. #12

    Регистрация
    16.06.2008
    Адрес
    Israel (Byalik)
    Возраст
    46
    Сообщений
    134
    Спасибо, почитаю. Жаль, что коментарии не видно, белеберда какая-то.

  16. #13
    VRV
    VRV вне форума

    Регистрация
    25.09.2009
    Адрес
    Sevastopol
    Возраст
    41
    Сообщений
    75
    Цитата Сообщение от Mishanya Посмотреть сообщение
    Спасибо, почитаю. Жаль, что коментарии не видно, белеберда какая-то.
    в блокноте открой-скорее всего с кодировкой трабл
    а вооще сам проект для разбора не самый удачный(хотя если разберешся-останеться ток жки подцепить)

  17. #14

    Регистрация
    16.06.2008
    Адрес
    Israel (Byalik)
    Возраст
    46
    Сообщений
    134
    Таймер бежит, результат на LCD каждый раз другой и разброс большой.
    Где-то ошибаюсь. Может, подскажите где?
    Прошу сильно не ругать.
    #include <mega8.h>
    #include <delay.h>
    #include <stdio.h>
    #include <lcd.h>

    void ppm_display (void);

    char lcd_buffer[33];
    int lcd_1,lcd_2;

    // Alphanumeric LCD Module functions
    #asm
    .equ __lcd_port=0x18 ;PORTB
    #endasm

    // External Interrupt 0 service routine
    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    if (PIND.2 == 1)
    {
    TIMSK=0x04; // Timer1 Overflow Interrupt Enable
    TCCR1A=0x00; // Timer1 Control Register A
    TCCR1B=0x01; // Start Timer1
    TCNT1H=0x00; // Timer1 TCNT1H
    TCNT1L=0x00; // Timer1 TCNT1L
    }
    else
    {
    TCCR1B=0x00; // stop Timer1
    lcd_1 = TCNT1L;
    lcd_2 = TCNT1H;
    ppm_display();
    }
    }

    //Timer 0 interrupt
    interrupt [TIM0_OVF] void timer0_ovf_isr(void)
    {

    }

    void main(void)
    {
    // Port B initialization
    PORTB=0xFF;
    DDRB=0xFF;

    // Port C,D initialization
    PORTC=0x00;
    DDRC=0x00;
    PORTD=0x00;
    DDRD=0x00;

    // Timer/Counter 1 initialization
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;

    // External Interrupt(s) initialization
    GICR|=0x40; // INT0: On
    MCUCR=0x01; // INT0 Mode: Any change
    GIFR=0x40; // INT1: Off

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x04;

    lcd_init(16); // LCD module initialization

    #asm("sei") // Global enable interrupts

    while (1)
    {
    }
    }

    void ppm_display (void)
    {
    #asm("cli")
    lcd_gotoxy(0,0);
    sprintf(lcd_buffer,"PPM L=%dms",lcd_1);
    lcd_puts(lcd_buffer);
    lcd_gotoxy(0,1);
    sprintf(lcd_buffer,"PPM H=%dms",lcd_2);
    lcd_puts(lcd_buffer);
    delay_ms(200); //delay 200ms
    lcd_clear(); //Lcd clear
    lcd_1 = 0x00;
    lcd_2 = 0x00;
    #asm("sei")
    }

  18. #15
    VRV
    VRV вне форума

    Регистрация
    25.09.2009
    Адрес
    Sevastopol
    Возраст
    41
    Сообщений
    75
    прочитай 10 пост.
    а вобще то сервртестер сам предполагает генерацию импульсов(те передатчик ненужен!), т.о. осушествляется генерация импульсов длительностью 1-2 мкс(например от данных крутилки->ацп) и периодом 20 мс.

  19. #16

    Регистрация
    16.06.2008
    Адрес
    Israel (Byalik)
    Возраст
    46
    Сообщений
    134
    Цитата Сообщение от VRV Посмотреть сообщение
    а вобще то сервртестер сам предполагает генерацию импульсов(те передатчик ненужен!), т.о. осушествляется генерация импульсов длительностью 1-2 мкс(например от данных крутилки->ацп) и периодом 20 мс.
    В том-то и дело, что мне передатчик нужен. А 10й пост я читал, но только мне он не как не помог.

  20. #17

    Регистрация
    19.07.2005
    Адрес
    Москва
    Возраст
    59
    Сообщений
    6,063
    Для начала вынести ppm_display(); из прерывания в main, пока Вы там отображаете на индикаторе что угодно может происходить, так никто не делает. И кстати на какой частоте у Вас все это происходит и что Вы в действительности смотрите канальный импульс или пакет PPM ?

  21. #18
    Учит правила
    Регистрация
    15.05.2009
    Адрес
    Москва
    Возраст
    54
    Сообщений
    1,672
    ...Ну и у ног же у Меги8 много, а задач у Вас - мало. Так используйте две ноги внешних прерываний. Перемкните их; одну (скажем, PD2) настройте на прерывание по фронту, другую (удобнее PB0 (=ICP1), но если PortB занят обслуживанием дисплея, то можно и PD3) настройте на прерывание по тылу. В Int0 будете таймер запускать, а в INT1 останавливать и ресетить.

    Я когда-то делал чем-то похожий дивайс - хронограф для измерения скорости пули пневматической винтовки. Разница только в том, что у меня были два сигнала - от старт- и стоп-оптопары. Камень - ATMEGA8535, сделано было примерно так:
    Код:
    //Управление прерываниями
    #define TOIE1  2 // Бит 2 (в регистре TIMSK)
    #define TEC1   5 // Бит 5 (в регистре TIMSK)
    #define INT0   6 // Бит 6 (в регистре GICR)
    #define TOV1   2 // Бит 2 (в регистре TIFR)
    #define ICF1   5 // Бит 5 (в регистре TIFR)
    #define INTF0  6 // Бит 6 (в регистре GIFR)
    
    #define I_T1Ovf_Enable  TIMSK |=  (1<<TOIE1) //Разрешить прер. переполнения T1
    #define I_T1Ovf_Disable TIMSK &= ~(1<<TOIE1) //Запретить прер. переполнения T1
    #define I_T1Cpt_Enable  TIMSK |=  (1<<TEC1)  //Разрешить прер. захвата T1
    #define I_T1Cpt_Disable TIMSK &= ~(1<<TEC1)  //Запретить прер. захвата T1
    #define I_INT0_Enable  GICR |=  (1<<INT0)    //Разрешить прер. INT0
    #define I_INT0_Disable GICR &= ~(1<<INT0)    //Запретить прер. INT0
    
    #define F_T1Ovf_Clr  TIFR |=  (1<<TOV1)      //Сброс флага прер. переполнения T1
    #define F_T1Ovf_Set  TIFR &= ~(1<<TOV1)      //Уст. флага  прер. переполнения T1
    #define F_T1Cpt_Clr TIFR |=  (1<<ICF1)       //Сброс флага прер. захвата T1
    #define F_T1Cpt_Set TIFR &= ~(1<<ICF1)       //Уст. флага прер. захвата T1
    #define F_INT0_Clr   GIFR |=  (1<<INTF0)     //Сброс флага прер. INT0
    #define F_INT0_Set   GIFR &= ~(1<<INTF0)     //Уст. флага прер. INT0
    
    
    // External Interrupt 0 service routine
    interrupt [EXT_INT0] void ext_int0_isr(void) {
       //TCCR1A=0x00; //Не нужно, ибо и так ==0.
        #ifdef OnNewton // Тестирование падающим сердечником
            TCCR1B=0x83;   // 288,000 kHz - захват с антидребезгом
        #else
            TCCR1B=0x81;   // 18432,000 kHz - захват с антидребезгом
        #endif
    
        I_INT0_Disable;     //Запрещаем реагировать на Int0
        I_T1Ovf_Enable;    //Разрешаем прерывание по переполнению - вдруг пропустим стоп...
        I_T1Cpt_Enable;    //Разрешаем прерывание ICP1 - ждем фронт стоп-импульса
        F_T1Ovf_Clr;        //Очищаем флаги прерываний
        F_T1Cpt_Clr;
        F_INT0_Clr;
    }
    
    
    // Timer 1 input capture interrupt service routine
    interrupt [TIM1_CAPT] void timer1_capt_isr(void) {
        resT=ICR1;   // Сохраняем подсчитанное значение
        TCCR1B=0x00;  // Останов таймера
        TCCR1A=0x00;
        TCNT1H=0x00; // Обнуляем таймер для последующего запуска
        TCNT1L=0x00;
    
        /*
            Здесь процедуры обсчета результата и занесения в значения в переменную,
            которая выводится на дисплей в основном цикле программы
       */
    
        I_INT0_Enable;       //Разрешаем прерывание Int0 - ждем фронт старт-импульса
        I_T1Ovf_Disable;    //Запрещаем прерывание по переполнению - таймер сейчас стоит
        I_T1Cpt_Disable;    //Запрещаем прерывание ICP1 - пока нет старта, стоп не ловим
        F_T1Ovf_Clr;         //Очищаем флаги прерываний
        F_T1Cpt_Clr;
        F_INT0_Clr;
    }
    Я эмбеддер не больно продвинутый; может, я тут слишком сильно "дую на воду" - но дивайс мой давно и успешно работает.
    Последний раз редактировалось EagleB3; 06.01.2010 в 21:32.

  22. #19

    Регистрация
    16.06.2008
    Адрес
    Israel (Byalik)
    Возраст
    46
    Сообщений
    134
    Цитата Сообщение от PigTail Посмотреть сообщение
    Для начала вынести ppm_display(); из прерывания в main, пока Вы там отображаете на индикаторе что угодно может происходить, так никто не делает. И кстати на какой частоте у Вас все это происходит и что Вы в действительности смотрите канальный импульс или пакет PPM ?
    Если я вынесу ppm_display(); из прерывания в main, как я буду обращаться к сабрутине void ppm_display(void)?
    Всё проиходит с чстотой 8MHz.
    Я хочу мереть положительную часть импульса от подъема до спада с приёмника, именно она отвечает за угол поворота сервы.

  23. #20
    Учит правила
    Регистрация
    15.05.2009
    Адрес
    Москва
    Возраст
    54
    Сообщений
    1,672
    Насчет 8 МГц - это ты маненько погорячился. Не все.
    16-ти битный таймер должен натикать 65535 значений не более чем за, скажем, 2.1mS (2mS+5%). Исходя из этого ты выбираешь наименьший допустимый делитель таймера. Если этот делитель =1 - ну, значит, и тик таймера у тебя тоже 8МГц.
    А дисплей обновлять - это песня отдельная. Тем более, HD44780 - с собственной оперативной памятью.
    Если хочешь обновлять непременно после _каждого_ пойманного импульса, то можешь поставить и в прерывание "тыла". Но тогда, пока выполняется функция обновления дисплея, все внешние прерывания должны быть запрещены. Успеешь закончить отображение и разрешить INT0 - поймаешь следующий импульс. Не успеешь - пропустишь следующий (или следующие...) импульсы.

    Только зачем так часто? Глаз все равно этого не оценит. Чаще 25 раз в секунду - только мультики рисовать.

    Взгляни на обычный код, который генерит CVAVR. Там инициализация камня, потом - цикл while.
    Вот внутри цикла while у тебя будет вывод на дисплей ( ppm_display(); ). Выводиться будет то, что посчитано в прерывании останова. Так часто, как это позволит содержимое прочих строк внутри while. Так что, скорее всего, еще и замедление (внутри while) ставить придется, чтобы цифры на дисплее не мельтешили. Два - три раза в секунду, а то и за значением следить не сможешь. Будут цифры мелькать, как сотые секунды на электронном секундомере. Оно тебе надо?
    А вот во время этих замедлений/простоев ты будешь замерять/обсчитывать свой импульс. "Обсчитывать" - скажем, можешь поставить осреднение медианным фильтром (сохраняешь некоторое число последних замеров (условно, 10); сортируешь по возрастанию, края (условно - по три значения) отбрасываешь; по оставшимся 4-м значениям считаешь среднее арифметическое и его показываешь).
    Последний раз редактировалось EagleB3; 06.01.2010 в 22:22.

  24. #21

    Регистрация
    19.07.2005
    Адрес
    Москва
    Возраст
    59
    Сообщений
    6,063
    Цитата Сообщение от Mishanya Посмотреть сообщение
    Если я вынесу ppm_display(); из прерывания в main, как я буду обращаться к сабрутине void ppm_display(void)?
    ...

    Я хочу мереть ... отвечает за угол поворота сервы.
    Это скорее можно назвать канальным импульсом, но не важно. В основном цикле например делаете проверку lcd_1 и lcd_2, если не нуль, то вызываете вывод на дисплей, прерывание должно коротко отрабатывать событие и выплевывать ход программы обратно, при вашей куче вызываемых в прерывании функций что там творится отследить невозможно.

  25. #22

    Регистрация
    28.07.2004
    Адрес
    Москва
    Возраст
    51
    Сообщений
    806
    В процедуре дисплея есть задержка на 200 мс. Обычно компиляторы делают её на таймере, уведомляя об это программиста только в документации. Если ppm_display рабочая, я-бы вообще без прерываний сделал, совсем их запретив. Обнуляем таймер и циклом ждём единицу на PPM ноге. По её приходу пускаем таймер, ждём обнуления ноги, и по событию сохраняем значение таймера. Полученое число отправляем в ЖК и терпеливо ждём возврата управления. И так по кольцу.
    Когда код заработает правильно, его уже можно "причесать" и усложнить по необходимости.

    ......
    Чтобы импульс гарантированно измерить с нарастающего фронта, перед ожиданием нарастания надо ещё добавить пустое ожидание спада.

  26. #23

    Регистрация
    01.12.2008
    Адрес
    Евпатория.Крым
    Возраст
    46
    Сообщений
    108
    http://forum.modelka.com.ua/index.ph...pic=19120&st=0
    вот здесь что-то подобное обсуждают но там под компорт
    а вобще можно и индикатор прикрутить

Закрытая тема

Похожие темы

  1. Продам Приёмники на 35, Т-конекторы, сервы стандарт индикатор и др...
    от samodelkin79 в разделе Барахолка. Аппаратура
    Ответов: 8
    Последнее сообщение: 19.11.2010, 23:50
  2. помогите найти РРМ сигнал
    от dimon_d3 в разделе Симуляторы
    Ответов: 4
    Последнее сообщение: 17.07.2010, 16:14
  3. Продам индикатор 2s Li-Po MaxPro световой/звуковой (в Москве)
    от oshirnin в разделе Барахолка. Аппаратура
    Ответов: 2
    Последнее сообщение: 05.07.2010, 10:52
  4. Помогите вытащить РРМ из Graupner MX-12
    от Alex@ndr в разделе Самодельная электроника, компьютерные программы
    Ответов: 5
    Последнее сообщение: 08.02.2007, 12:19
  5. одночиповый декодер РРМ и рулевая из шагового двигателя
    от RW9UAO в разделе Самодельная электроника, компьютерные программы
    Ответов: 13
    Последнее сообщение: 13.04.2004, 12:27

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения