Страница 1 из 6 123456 ПоследняяПоследняя
Показано с 1 по 10 из 54
  1. #1
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    60
    Сообщений
    241
    Вес репутации
    220

    По умолчанию PPM энкодер на ...дуино

    Так как для чтения 6 и более каналов приемника, требуется не реальное количество прерываний. Забравшись в плату приемника я легко нашел еще не декодированный сигнал PPM и теперь можно этот сигнал, одним проводом подать на один вход контроллера ардуины и задействовать только одно прерывание.
    Есть много примеров декодеров, но практически все используют PulseIn(), а я заметил большую погрешность этой функции. Может кто занимался в этом направлении или подскажет где подсмотреть механизм декодирования с относительно высокой достоверностью.

    p.s. Вот нашел библиотеку, может ее использовать и не морочить голову?
    Последний раз редактировалось Chip; 25.03.2017 в 18:25.
    Мои проекты - Катер для рыбалки

  2. #2
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,382
    Вес репутации
    10

    По умолчанию Re: PPM энкодер на ...дуино

    Попробуй . Если не подойдет что нибудь придумаем

  3. #3
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    60
    Сообщений
    241
    Вес репутации
    220

    По умолчанию Re: PPM энкодер на ...дуино

    Спасибо, я реально сам не разберусь.

    С мегой не заработала, пока разбирался с портами, то нашел еще вариант. Как-то больше доверия

    Пожалуйста, если сразу видно проблемность кода, тормозните.
    Я так понял из библиотеки, что можно использовать на выбор любой из 3-х таймеров? С мегой работать будет?

    PHP код:
    #include <PinChangeInt.h>    // http://www.arduino.cc/playground/Main/PinChangeInt
    #include <PinChangeIntConfig.h>
    #include <TimerOne.h>        // http://www.arduino.cc/playground/Code/Timer1

    #define NO_PORTB_PINCHANGES //PinChangeInt setup
    #define NO_PORTC_PINCHANGES    //only port D pinchanges (see: http://www.arduino.cc/playground/Learning/Pins)
    #define PIN_COUNT 3    //number of channels attached to the reciver
    #define MAX_PIN_CHANGE_PINS PIN_COUNT

    #define RC_TURN 3    //arduino pins attached to the reciver
    #define RC_FWD 2
    #define RC_FIRE 4
    byte pin[] = {RC_FWDRC_TURNRC_FIRE};    //for maximum efficency thise pins should be attached
    unsigned int time[] = {0,0,0};                // to the reciver's channels in the order listed here

    byte state=0;
    byte burp=0;    // a counter to see how many times the int has executed
    byte cmd=0;     // a place to put our serial data
    byte i=0;       // global counter for tracking what pin we are on

    void setup() {
        
    Serial.begin(115200);
        
    Serial.print("PinChangeInt ReciverReading test");
        
    Serial.println();            //warm up the serial port

        
    Timer1.initialize(2200);    //longest pulse in PPM is usally 2.1 milliseconds,
                                    //pick a period that gives you a little headroom.
        
    Timer1.stop();                //stop the counter
        
    Timer1.restart();            //set the clock to zero

        
    for (byte i=0i<3i++)
        {
            
    pinMode(pin[i], INPUT);     //set the pin to input
            
    digitalWrite(pin[i], HIGH); //use the internal pullup resistor
        
    }
        
    PCintPort::attachInterrupt(pin[i], rise,RISING); // attach a PinChange Interrupt to our first pin
    }

    void loop() {
        
    cmd=Serial.read();        //while you got some time gimme a systems report
        
    if (cmd=='p')
        {
            
    Serial.print("time:\t");
            for (
    byte i=0i<PIN_COUNT;i++)
            {
                
    Serial.print(i,DEC);
                
    Serial.print(":");
                
    Serial.print(time[i],DEC);
                
    Serial.print("\t");
            }
            
    Serial.print(burpDEC);
            
    Serial.println();
    /*      Serial.print("\t");
            Serial.print(clockCyclesToMicroseconds(Timer1.pwmPeriod), DEC);
            Serial.print("\t");
            Serial.print(Timer1.clockSelectBits, BIN);
            Serial.print("\t");
            Serial.println(ICR1, DEC);*/
        
    }
        
    cmd=0;
        switch (
    state)
        {
            case 
    RISING//we have just seen a rising edge
                
    PCintPort::detachInterrupt(pin[i]);
                
    PCintPort::attachInterrupt(pin[i], fallFALLING); //attach the falling end
                
    state=255;
                break;
            case 
    FALLING//we just saw a falling edge
                
    PCintPort::detachInterrupt(pin[i]);
                
    i++;                //move to the next pin
                
    PIN_COUNT;  //i ranges from 0 to PIN_COUNT
                
    PCintPort::attachInterrupt(pin[i], rise,RISING);
                
    state=255;
                break;
            
    /*default:
                //do nothing
                break;*/
        
    }
    }

    void rise()        //on the rising edge of the currently intresting pin
    {
        
    Timer1.restart();        //set our stopwatch to 0
        
    Timer1.start();            //and start it up
        
    state=RISING;
    //  Serial.print('r');
        
    burp++;
    }

    void fall()        //on the falling edge of the signal
    {
        
    state=FALLING;
        
    time[i]=readTimer1();    // read the time since timer1 was restarted
    //  time[i]=Timer1.read();    // The function below has been ported into the
                                // the latest TimerOne class, if you have the
                                // new Timer1 lib you can use this line instead
        
    Timer1.stop();
    //  Serial.print('f');
    }

    unsigned long readTimer1()        //returns the value of the timer in microseconds
    {                                    //rember! phase and freq correct mode counts 
                                        //up to ICR1 then down again
        
    unsigned int tmp=TCNT1;
        
    char scale=0;
        switch (
    Timer1.clockSelectBits)
        {
        case 
    1:// no prescalse
            
    scale=0;
            break;
        case 
    2:// x8 prescale
            
    scale=3;
            break;
        case 
    3:// x64
            
    scale=6;
            break;
        case 
    4:// x256
            
    scale=8;
            break;
        case 
    5:// x1024
            
    scale=10;
            break;
        }
        while (
    TCNT1==tmp//if the timer has not ticked yet
        
    {
            
    //do nothing -- max delay here is ~1023 cycles
        
    }
        
    tmp = (  (TCNT1>tmp) ? (tmp) : (ICR1-TCNT1)+ICR1  );//if we are counting down add the top value
                                                            //to how far we have counted down
        
    return ((tmp*1000L)/(F_CPU /1000L))<<scale;

    Вложения Вложения
    Последний раз редактировалось Mastar; 22.11.2011 в 18:09.
    Мои проекты - Катер для рыбалки

  4. #4
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    60
    Сообщений
    241
    Вес репутации
    220

    По умолчанию Re: PPM энкодер на ...дуино

    Вот мой РРМ сигнал на фото.
    Период 22 мс.
    Стробирующий положительный импульс 0,5 мс.
    1 канал - отрицательный импульс 1,0 мс.
    Стробирующий положительный импульс 0,5 мс.
    2 канал - отрицательный импульс 1,0 мс.
    Стробирующий положительный импульс 0,5 мс.
    3 канал - отрицательный импульс 1,5 мс.
    Стробирующий положительный импульс 0,5 мс.
    4 канал - отрицательный импульс 1,0 мс.
    Стробирующий положительный импульс 0,5 мс.
    и т.д.
    Миниатюры Миниатюры Нажмите на изображение для увеличения. 

Название:	PPM Futaba FP-R128DF.jpg 
Просмотров:	2100 
Размер:	110.0 Кб 
ID:	13455  
    Мои проекты - Катер для рыбалки

  5. #5
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    60
    Сообщений
    241
    Вес репутации
    220

    По умолчанию Re: PPM энкодер на ...дуино

    А это шум при отключенном передатчике, установки осциллографа те же.

    После включения передатчика и до конца инициализации на выходе появляется ноль, а потом пошли пачки сигналов.
    Миниатюры Миниатюры Нажмите на изображение для увеличения. 

Название:	PPM Futaba FP-R128DF NS.jpg 
Просмотров:	2067 
Размер:	99.4 Кб 
ID:	13456  
    Последний раз редактировалось Mastar; 22.11.2011 в 19:27.
    Мои проекты - Катер для рыбалки

  6. #6
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    60
    Сообщений
    241
    Вес репутации
    220

    По умолчанию Re: PPM энкодер на ...дуино

    А может забыть про универсальные библиотеки, а начать самостоятельно писать и навыки в программировании получу и другим возможно поможет.

    Длительность канального отрицательного импульса регулируется передатчиком в пределах 0,5 - 1,5 мс.
    Синхроимпульсы вначале, между каналами и в конце, все по 0,5 мс.
    Пауза после пачки 5,8 - 13,8 мс.
    Период, как я уже писал немного более 22 мс.

    После пачки сигналов, минимальная пауза 5,8 мс.
    Значит ловим 5 мс. отрицательных и обнуляем счетчик каналов.
    Ждем первого перехода с 1 в 0, после которого таймер отсчитывает длительность отрицательного импульса и присваивает это значение первому каналу.
    Увеличиваем счетчик каналов на 1.
    Все в цикле до прихода паузы длительностью более 5 мс.
    Последний раз редактировалось Mastar; 22.11.2011 в 19:39.
    Мои проекты - Катер для рыбалки

  7. #7
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,382
    Вес репутации
    10

    По умолчанию Re: PPM энкодер на ...дуино

    Не пойму у тебя он что цифру выдает?

  8. #8
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    60
    Сообщений
    241
    Вес репутации
    220

    По умолчанию Re: PPM энкодер на ...дуино

    Цитата Сообщение от Chip Посмотреть сообщение
    Не пойму у тебя он что цифру выдает?
    Я просто сигнал взял со входа триггера внутри приемника, я могу его легко инвертировать и подтянуть к 5 вольтам. Там питание триггера 3,3 .
    Мои проекты - Катер для рыбалки

  9. #9
    Продвинутый
    Регистрация
    28.11.2010
    Возраст
    60
    Сообщений
    241
    Вес репутации
    220

    По умолчанию Re: PPM энкодер на ...дуино

    Сегодня ночью появилось время и я продолжил.

    PHP код:
    #include <TimerOne.h>
    #include <TinyGPS.h>
    #include <EEPROM.h>
    #include <Servo.h>

    volatile uint16_t timerCount;
    #define BTNPIN 2 //Входной сигнал PPM
    int ppmImpuls[9]; // Массив импульсов для паузы и 8 каналов
    int chImpuls[9] = {1000100100100100100100100100}; // Массив средних значений для паузы и 8 каналов
    int chanel // Номер канала
    int minImpuls 45 // Минимальный импульс (450 us)
    int maxImpuls 155// Максимальный импульс (1550 us)
    int minPausa 500// Минимальная пауза (5000 us)
    int maxPausa 1300// Максимальная пауза (13000 us)
    Servo servo1;
    Servo servo2;

    void setup()    
    {      
      
    servo1.attach(37);
      
    servo2.attach(36);
      
    servo1.writeMicroseconds(1500); // устанавливает привод в среднее положение
      
    servo2.writeMicroseconds(1500); // устанавливает привод в среднее положение
      
    Serial.begin(115200);
      
    pinMode (BTNPININPUT);
      
    Timer1.initialize(10);                  
      
    Timer1.attachInterrupt(callback);
      
    attachInterrupt(0impDownRISING);
    }    

    void loop()    
    {      
      for (
    int i=0<= 8i++)
        {
          
    chImpuls[i] = (chImpuls[i] + ppmImpuls[i]) / // усреднение 3 импульсов
          //Serial.print(i); Serial.print("="); 
          //Serial.print(chImpuls[i]); Serial.print(" ");
        
    }     
          
    Serial.println("");
          
    //delay (200);
          
    servo1.writeMicroseconds(chImpuls[1]*10); 
          
    servo2.writeMicroseconds(chImpuls[2]*10); 
    }  

    void callback() { timerCount++; } //--------- Счетчик------------

    void impUp() //---------- Функция обработки положительного импульса   
    {
      
    detachInterrupt(0);
      
    timerCount=0;
      
    attachInterrupt(0impDownRISING);    
    }    

    void impDown() // Функция обработки отрицательного импульса

      
    int ppm timerCount;
      
    detachInterrupt(0);
      if( 
    ppm minPausa ) { chanel=; } else { chanel ++ ; }
      
    ppmImpuls[chanel] = ppm ;
      
    attachInterrupt(0impUpFALLING);   

    Файл-сафе теперь нужно реализовывать.
    Что можно сделать с контролем над сигналом, шум подвешивает порт. Также перестают сервы следить за положением стиков. Резет при вкл. передатчике, все работает, но до выключения передатчика.
    Последний раз редактировалось Mastar; 24.11.2011 в 10:03.
    Мои проекты - Катер для рыбалки

  10. #10
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,382
    Вес репутации
    10

    По умолчанию Re: PPM энкодер на ...дуино

    Нужно делать программный фильтр шума.
    Самый простой способ : сделать три, четыре или пять замеров длительности периода и считать что это достоверный сигнал.

Страница 1 из 6 123456 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 3 (пользователей: 0 , гостей: 3)

Ваши права

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