Помогите разобраться с arduino Nano и PPM
- Войдите на сайт для отправки комментариев
Пнд, 06/07/2015 - 00:37
Доброго времени суток, господа.
Сказу оговорюсь, с ардуино совсем "на вы". Есть задача:
На входе PPM сигнал(https://en.wikipedia.org/wiki/Pulse-position_modulation) 8 каналов.
Необходимо получить на выходе PPM сигнал, но поменять местами 2 канала.
Есть код, который, впринципе, с этой задачей справился, но есть одно но. Значения каналов на выходе колеблются в пределах 0,1 мсек, при неизменном входном сигнале. Во время отладки
платформа Arduino nano 328p
Прошу помощи в этом вопросе. Заранее благодарен.
код:
//this programm will put out a PPM signal //////////////////////CONFIGURATION/////////////////////////////// #define chanel_number 8 //set the number of chanels #define default_servo_value 0 //set the default servo value #define PPM_FrLen 22500 //set the PPM frame length in microseconds (1ms = 1000µs) #define PPM_PulseLen 300 //set the pulse length #define onState 0 //set polarity of the pulses: 1 is positive, 0 is negative #define sigPin 10 //set PPM signal output pin on the arduino ////////////////////////////////////////////////////////////////// /*this array holds the servo values for the ppm signal change theese values in your code (usually servo values move between 1000 and 2000)*/ int *ppm[chanel_number]; int ppm_in[chanel_number]; void setup(){ //initiallize default ppm values for(int i=0; i<chanel_number; i++){ ppm[i] = &ppm_in[i]; *ppm[i]= default_servo_value; } ppm[0] = &ppm_in[1]; ppm[1] = &ppm_in[0]; pinMode(sigPin, OUTPUT); digitalWrite(sigPin, !onState); //set the PPM signal pin to the default state (off) pinMode(2, INPUT); //Pin 3 as input cli(); TCCR1A = 0; // set entire TCCR1 register to 0 TCCR1B = 0; OCR1A = 100; // compare match register, change this TCCR1B |= (1 << WGM12); // turn on CTC mode TCCR1B |= (1 << CS11); // 8 prescaler: 0,5 microseconds at 16mhz TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt sei(); } void loop(){ while(pulseIn(2, LOW) < 5000){ } //Wait for the beginning of the frame for(int x=0; x<=chanel_number-1; x++)//Loop to store all the channel position { ppm_in[x]=pulseIn(2, LOW)+400; } } ISR(TIMER1_COMPA_vect){ //leave this alone static boolean state = true; TCNT1 = 0; if(state) { //start pulse digitalWrite(sigPin, onState); OCR1A = PPM_PulseLen * 2; state = false; } else{ //end pulse and calculate when to start the next pulse static byte cur_chan_numb; static unsigned int calc_rest; digitalWrite(sigPin, !onState); state = true; if(cur_chan_numb >= chanel_number){ cur_chan_numb = 0; calc_rest = calc_rest + PPM_PulseLen;// OCR1A = (PPM_FrLen - calc_rest) * 2; calc_rest = 0; } else{ OCR1A = (*ppm[cur_chan_numb] - PPM_PulseLen) * 2; calc_rest = calc_rest + *ppm[cur_chan_numb]; cur_chan_numb++; } } }
Поправка: он на этапе чтения допускает эту погрешность. То есть, выводя в консоль значения, полученные со входа уже давали такую погрешность. То есть проблема с чтением сигнала, а не с генерацией.
Поменять местами 2 проводка?
Писец... скоро будут спрашивать как в розетку вилку втыкать?
полётный контроллер соединяется с приёмником 3-мя проводками 5v, gnd и ppm. Там нет этих 2-х проводков.
На аппаратуре ( передатчике) разве нельзя в микшерах поменять каналы?
Или это что-то жёстко забито и не программируется?
Если оба сервы- переключить....
Если джойстики - перекинуть их каналы
На аппаратуре ( передатчике) разве нельзя в микшерах поменять каналы?
Или это что-то жёстко забито и не программируется?
Если оба сервы- переключить....
Если джойстики - перекинуть их каналы
Вот вы пля все умные!!!
Человек не зря спрашивает. Нихуа там не поменяешь. Не во всех аппах каналы можно переназначить.
Скорее всег овпрост по совместимости Futaba/JR или что то типа. Порядок каналов другой. Газ с высотой перепутаны.
Перекинуть провода джойстиков - не вариант. Пробовал. На газ нет экспоненты например, и еще есть програмные привязки, триммеры опять же. Там много интересного. Проще в дуне перекинуть порядок каналов.
Или купить Турнигу 9XR за 50 доларов, она и в JR и Futabе выдает PPM и каналы любые на любые настраиваются.
er9x, и это правильно!
На аппаратуре ( передатчике) разве нельзя в микшерах поменять каналы?
Или это что-то жёстко забито и не программируется?
Если оба сервы- переключить....
Если джойстики - перекинуть их каналы
Вот вы пля все умные!!!
Человек не зря спрашивает. Нихуа там не поменяешь. Не во всех аппах каналы можно переназначить.
Скорее всег овпрост по совместимости Futaba/JR или что то типа. Порядок каналов другой. Газ с высотой перепутаны.
Перекинуть провода джойстиков - не вариант. Пробовал. На газ нет экспоненты например, и еще есть програмные привязки, триммеры опять же. Там много интересного. Проще в дуне перекинуть порядок каналов.
Или купить Турнигу 9XR за 50 доларов, она и в JR и Futabе выдает PPM и каналы любые на любые настраиваются.
Ни прибавить, ни отнять. элеватор с элеронами. RDS8000 мать её. И менять не хочу - эту уже затюнил, но вот чехарда с каналами всё испортила.
Немного разобрался. Но проблема осталась. При использовании pulseIn появляется большая погрешность. Духи в онлайне говорят, что тут для точности лучше использовать таймер. Действительно, нашел рабочий пример, который выдаёт погрешность в 1 наносекунду, что приемлимо. Но вот незадача. на ардуино нано, который я использую, 3 таймера 0й и 2й 8-битный и 1 16 битный. Для моей задачи требуется 2 таймера 16 бит. Как можно выти из данной ситуации? Или посоветуйте платформу с 2 16-битными таймерами, которая по размеру не больше нано.
Пока что приходит на ум только запользовать 2 нано - один читает и передаёт по TTL на другой, а второй генерит сигнал. Но на мой взгляд - это очень большой костыль. Я точно знаю, есть решенее элегантнее.
Я бы сделал так, попробую на словах:
У нас приходит 8 импульсов. Период их известен и пауза между пачками тоже.
16-ти битовым таймером достаточно точно измеряем длительности каждого импульса и складываем в массив.
В массиве меняем что нам нужно местами и во время когда должна прийти вторая пачка воспроизводим нашу.
Минус всего этого- мы пропускаем одну пачку.
Хотя не думаю что это так смертельно, ведь пальчики управляющие джойстиками работают намного медленнее
Дэфалтные настройки ППМ от Турниги с прошивкой er9x, скриншот программы eepe:
Вот подробнее про эти настройки:
Ещё: http://www.fpv-hero.de/Images/PPM1.jpg
Я бы сделал так, попробую на словах:
У нас приходит 8 импульсов. Период их известен и пауза между пачками тоже.
16-ти битовым таймером достаточно точно измеряем длительности каждого импульса и складываем в массив.
В массиве меняем что нам нужно местами и во время когда должна прийти вторая пачка воспроизводим нашу.
Минус всего этого- мы пропускаем одну пачку.
Хотя не думаю что это так смертельно, ведь пальчики управляющие джойстиками работают намного медленнее
Благодарю за ответ. Сегодня попробую сделать смешнее. Я попробую использовать все три таймера. При этом для генерации 16 битный, а для считывания 2 8 битных, при этом сделать на одном делитель 1024, а на другом 8. И использовать их как старший и младший байт. То есть попытаться сделать из 2х 8 битных таймеров 1 16 битный.
Можно-же один много раз запускать для генерации выходного сигнала.......
Тогда можно без потери пакетов сразу передавать его по окончанию приёма.
Будет задержка на один пакет. То есть около 40 миллисекунд.
Один таймер16 пишет в массив, другой 8 читает и воспроизводит.
Так проблема-то в том, что 8 бит не хватает, чтоб адекватно хранить задержку с высокой точностью. То есть 8 бит оперирует числами 0-256, чего не хватает для хранения 900-2500. Поэтому и хочу пользовать 2 8 битных. А чтение/запись вообще хочу делать ассинхронно, то есть есть массив. По прерыванию int0(изменения ноги 2) туда впихиваются значения таймера, при этом по прерыванию второго таймера они пишутся в выход. То есть я loop() задействую только для отладки. В этом случае задержка может варьироваться от 0 до 22 мс.
Сосчитать таймером до 256 4 раза будет 1024 ( примерно) 10 раз - 2560
Фактически нужно просто подсчитывать моменты его переполнения.
А по кругу он зациклится сам.
Ну и потом добавить немного сколько надо , хотя, конечно, на перезапись таймера возможно время неучтённое потратится.
Недавно вроде подобное было на форуме в виде функции.
Хм... тоже интересно, попробую сегодня, спасибо!
Всем спасибо за комментарии и советы! Долго и
упоротоупорно пытался завести на ардуино нано. Ничего из выше предложенного не сработало :) Поступил проще - заказал ардуино про мини на атмеге 32u4, где есть 2 таймера по 16 бит. И вгрузил в него вот что:Всё взлетело и работает - каналы подменяются!