Я имею дело с мега квадрокоптером Arduino и пытаюсь сделать частоту ШИМ для 4 двигателей — 400 Гц каждый.
Я нашел интересное решение, в котором 4 16-битных таймера ATmega2560 используются для управления 4 ESC с помощью ШИМ, чтобы он мог достигать частоты 400 Гц. От 700 до 2000 мкс — нормальная ширина импульса, с которой имеет дело ESC.
1 с / REFRESH_INTERVAL = 1 / 0,0025 = 400 Гц.
this is servo.h lib:
#define MIN_PULSE_WIDTH 700 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2000 // the longest pulse sent to a servo
#define DEFAULT_PULSE_WIDTH 1000 // default pulse width when servo is attached
#define REFRESH_INTERVAL 2500 // minimum time to refresh servos in microseconds
#define SERVOS_PER_TIMER 1 // the maximum number of servos controlled by one timer
#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
Проблема состоит в том, чтобы заставить его работать, каждый ШИМ должен управляться с 1 16-битным таймером. В противном случае, скажем, 2 escs на 1 таймер даст 200 Гц. Таким образом, все 16-битные таймеры заняты управлением 4 ESC, но мне все еще нужно прочитать входную PPM от приемника. Для этого мне нужен как минимум еще один 16-битный таймер, которого у меня больше нет.
Это все еще один свободный 8-битный таймер, он может читать только цифры 0..255, в то время как обычные числа escs работают с 1000..2000 и так далее.
Так что произойдет, если я буду использовать один и тот же 16-битный таймер для чтения как pwm, так и ppm? Будет ли это работать? Будет ли это резко снизить скорость?
У меня есть arduino, работающий в паре с Raspberry Pi, который управляет фильтрацией данных, отладкой и прочим, лучше ли перенести чтение ppm в Raspberry?
Чтобы ответить на один из ваших вопросов:
Так что же произойдет, если я буду использовать один и тот же 16-битный таймер для PWM и PPM
чтение? Будет ли это работать?
Да. Когда срабатывает прерывание смены булавки, вы можете просто читать текущее значение TCNT, чтобы узнать, сколько времени прошло с момента последнего. Это никоим образом не повлияет на работу аппаратного ШИМ таймера.
Будет ли это резко снизить скорость?
Нет. ШИМ выполняется специальным оборудованием, программные операции, работающие в то же время, не влияют на его скорость, равно как и любые ISR, которые вы могли активировать для соответствующего таймера. Следовательно, вы можете позволить таймеру сгенерировать ШИМ по своему усмотрению и при этом использовать его для а) считывания с него текущего значения счетчика и б) привязки к нему выходного сравнения и / или переполнения ISR для создания расширенного программным таймером.
Отредактируйте в ответ на ваш комментарий:
Обратите внимание, что фактическим значением в регистре TCNT является текущий счетчик таймера (тика) в любой момент, независимо от того, активен ли ШИМ или нет. Кроме того, прерывание Timer OVerflow (TOV) можно использовать в любом режиме. Эти два свойства позволяют создать программно-расширенный таймер для произвольных других задач измерения времени с помощью следующих шагов:
timer1OvfCount
например), который эффективно подсчитывает переполнения таймера и таким образом расширяет фактический диапазон таймера. Текущий абсолютный счетчик тиков может быть рассчитан как timer1OvfCount * topTimerValue + TCNTx
, timer1OvfCount
и сохранить эти значения в другой глобальной переменной (например, startTimestamp
), эффективно начиная ваше измерение времени.timer1OvfCount
, Теперь у вас есть отметка времени начала сигнала в startTimestamp
и отметка времени окончания сигнала в другой переменной. Разница между этими двумя временными метками заключается именно в продолжительности импульса, который вы ищете.Однако следует учитывать два момента:
timer1OvfCount
и ТОВ ИЗР. Этому можно противостоять, отключая прерывания, затем читая TCNT, затем читая timer1OvfCount
и затем проверка флага прерывания TOV; если флаг установлен, есть ожидающие, необработанные прерывания переполнения -> включить прерывания и повторить.Тем не менее, я уверен, что есть несколько библиотечных функций для поддержки программно-расширенных таймеров / счетчиков, которые выполняют всю обработку таймера за вас.
что такое единица измерения 700 и 2000? Я полагаю, что вы используете. Вы не очень-то объяснили в своем вопросе, но я определил, что вам нужны импульсы длительностью 25 мсек, при которых 700 мксек на время могут быть 0 градусов, а 2000 — на 180 градусов, теперь импульсный вход каждого сервопривода можно подключить к любому GPIO AVR. И эти GPIO предоставляют сигнал ШИМ серво. Так что, я думаю, вы даже можете управлять всеми этими двигателями только за один раз. С этим кодом:
Предположим, у вас есть таймер, который генерирует Inturrupt на каждые 50 месяцев.
Теперь, если вы хотите 700 мксек для мотора 1800 мцек для мотора 2 900 мцек для мотора 3 & 1000 мксек для двигателя 4, тогда просто сделайте это:
#define CYCLE_PERIOD 500 // for 25 msec = 50 usec * 500
unsigned short motor1=14; // 700usec = 50x14
unsigned short motor2=16; // 800usec
unsigned short motor3=18; // 900usec
unsigned short motor4=20; // 1000usec
unsigned char motor1_high_flag=1;
unsigned char motor2_high_flag=1;
unsigned char motor3_high_flag=1;
unsigned char motor4_high_flag=1;
PA.0 = 1; // IO for motor1
PA.1 = 1; // IO for motor2
PA.2 = 1; // IO for motor3
PA.3 = 1; // IO for motor4
void timer_inturrupt_at_50usec()
{
motor1--;motor2--;motor3--;motor4--;
if(!motor1)
{
if(motor1_high_flag)
{
motor1_high_flag = 0;
PA.0 = 0;
motor1 = CYCLE_PERIOD - motor1;
}
if(!motor1_high_flag)
{
motor1_high_flag = 1;
PA.0 = 1;
motor1 = 14; // this one is dummy;if you want to change duty time update this in main
}
}
if(!motor2)
{
if(motor2_high_flag)
{
motor2_high_flag = 0;
PA.1 = 0;
motor2 = CYCLE_PERIOD - motor2;
}
if(!motor2_high_flag)
{
motor2_high_flag = 1;
PA.1 = 1;
motor2 = 16;
}
}if(!motor3)
{
if(motor3_high_flag)
{
motor3_high_flag = 0;
PA.2 = 0;
motor3 = CYCLE_PERIOD - motor3;
}
if(!motor3_high_flag)
{
motor3_high_flag = 1;
PA.2 = 1;
motor3 = 18;
}
}
if(!motor4)
{
if(motor4_high_flag)
{
motor4_high_flag = 0;
PA.3 = 0;
motor4 = CYCLE_PERIOD - motor4;
}
if(!motor4_high_flag)
{
motor4_high_flag = 1;
PA.3 = 1;
motor4 = 19;
}
}
}
& скажи мне, что такое ESC?