Последний раз редактировалось Mastar; 24.11.2011 в 22:56.
Мои проекты - Катер для рыбалки
Получилась ерунда, значения не достоверные.PHP код:
#include <TimerOne.h>
volatile uint16_t timerCount0, timerCount1;
#define BTNPIN 2 //Входной сигнал PPM
int ppmImpuls[9]; // Массив импульсов для паузы и 8 каналов
int chImpuls[9] = {1000, 100, 100, 100, 100, 100, 100, 100, 100}; // Массив средних значений для паузы и 8 каналов
int chanel = 0 ; // Номер канала
int minImpuls = 45 ; // Минимальный импульс (450 us)
int maxImpuls = 155; // Максимальный импульс (1550 us)
int minPausa = 500; // Минимальная пауза (5000 us)
int maxPausa = 1300; // Максимальная пауза (13000 us)
int ppm1 = 0 ;
void setup()
{
Serial.begin(115200);
pinMode (BTNPIN, INPUT);
Timer1.initialize(10);
Timer1.attachInterrupt(callback);
attachInterrupt(0, impDown0, RISING);
attachInterrupt(1, impUp1, FALLING);
}
void loop()
{
for (int i=1; i <= 8; i++)
{
chImpuls[i] = (4 * chImpuls[i] + ppmImpuls[i]) / 5 ; // усреднение 3 импульсов
Serial.print(i); Serial.print("=");
Serial.print(chImpuls[i]); Serial.print(" p=");
Serial.print(ppm1); Serial.print(" ");
delay (100);
}
Serial.println("");
}
void callback() //--------- Счетчик------------
{
timerCount0++;
timerCount1++;
}
void impUp0() //---------- Функция обработки положительного импульса по таймеру 0
{
detachInterrupt(0);
timerCount0=0;
attachInterrupt(0, impDown0, RISING);
}
void impDown0() // Функция обработки отрицательного импульса по таймеру 0
{
int ppm0 = timerCount0;
detachInterrupt(0);
if( ppm0 > minPausa ) { chanel=0 ; } else { chanel ++ ; }
ppmImpuls[chanel] = ppm0 ;
attachInterrupt(0, impUp0, FALLING);
}
void impUp1() //---------- Функция обработки положительного импульса по таймеру 1
{
ppm1 = timerCount1;
detachInterrupt(1);
attachInterrupt(1, impDown0, RISING);
}
void impDown1() // Функция обработки отрицательного импульса по таймеру 1
{
detachInterrupt(1);
timerCount1=0;
attachInterrupt(1, impUp0, FALLING);
}
Мои проекты - Катер для рыбалки
Вот набросал болванку , для захвата длительностей импульсов в два массива , один с длительностями положительных импульсов другой соответственно с отрицательными . В главном цикле можно делать обработку этих импульсов, разрешение таймера очень высокое, равно 8 тактам процессора 0.0000005 , это значит максимальная длительность импульса на входе D2 не должна быть больше чем 32 мс
PHP код:
volatile uint8_t i=0;
volatile uint8_t Counter=0;
volatile uint16_t Time=0;
volatile uint16_t Bit_High[255];
volatile uint16_t Bit_Low[255];
//*************************************************************************
ISR(INT0_vect) // обработчик внешнего прерывания
{
Time=TCNT1;
if (PIND & (1<<2)) // Если бит 2 порта D установлен в лог. 1
{
Bit_High[i]=Time;
} else
{
Bit_Low[i]=Time;
}
i++;
TCNT1 = 0; //обнулить счетчик таймера
}
//*************************************************************************
void setup()
{
pinMode(2, INPUT);
pinMode(13, OUTPUT);
digitalWrite(2, HIGH); // включить подтяжку входа
Serial.begin(115200);
Init_Timer1();
Init_Ext_Int0();
}
//*************************************************************************
void loop()
{
//.......
}
//*************************************************************************
void Init_Ext_Int0()// инициализация прерывания int0
{
EICRA &= ~((1<<ISC00)|(1<<ISC01)); //прерывание вызавается при сигнале LOW
EICRA |= (1<<ISC00); // прерывание вызывается при спадающем или нарастающем фронте сигнала на входе;
EIMSK |= (1<<INT0); // разрешить прерывание INT0;
sei(); //разрешить все прерывания
}
//*************************************************************************
void Init_Timer1()// инициализация таймера
{
TCCR1A = 0; //Normal mode
TCCR1B = (1<< CS11); //предделителm x8
TCNT1 = 0; //обнулить счетчик таймера
TIMSK1 = _BV(TOIE1); // Включить прерывание по переполнению таймера
sei(); //разрешить все прерывания
}
//*************************************************************************
ISR(TIMER1_OVF_vect)//вектор прерывания по переполнению счетчика
{
//Counter++;
TCNT1=0;
}
Последний раз редактировалось Chip; 25.11.2011 в 02:29.
Спасибо, не заработал, возможно мне под мегу нужно менять.
if (PIND & (1<<2)) // Если бит 2 порта D установлен в лог. 1
У меня сервы на порту С, PINС или PORTC, так как я понял PIN только на чтение работает или я и тут ошибаюсь?
Если помните, я притормозил развитие темы http://www.compcar.ru/forum/showpost...7&postcount=41
Последний раз редактировалось Mastar; 25.11.2011 в 02:31.
Мои проекты - Катер для рыбалки
PIND это D2 на Arduino 328, 168
С мегой сложнее, нужно даташиты курить для изучения битов конфигурации таймера и т.д. Но самого главного ты не заметил , В этом скетче можно конфигурировать любое из 8-ми внешнее прерывание для меги . В итоге можно получить 8 внешних прерываний
Порт работает на чтение конечно
Последний раз редактировалось Chip; 25.11.2011 в 13:41.
Тогда я перепаяю на порт С, мне так удобнее.
Если отказаться в моем примере от привязки к пинам ардуины, а перейти на порты, то получается, что РРМ сигнал нужно подавать на порт С2?
Мои проекты - Катер для рыбалки
На Arduino mega PortD выводы 43-46 (INT0-INT3) и PortE выводы 6,7,8,9(INT4-INT7)
регистры управления внешними прерываниями
EICRA -для конфигурации прерываний INT0-INT3
EICRB -для конфигурации прерываний INT4-INT7
EIMSK -Разрешение на внешнее прерывание INT7 – INT0
подробно здесь
обработчики вставляй в любом месте
пример обработчика:
PHP код:
ISR(INT7_vect) // обработчик внешнего прерывания
{
...
}
Последний раз редактировалось Chip; 25.11.2011 в 03:45.
Вот еще момент, сигнал с выхода приемника достаточный для чтения, поэтому digitalWrite(2, HIGH) думаю не буду подкидывать.
Мои проекты - Катер для рыбалки
Если вход при каких либо ситуациях в воздухе не будет висеть то нет смысла подтягивать
Кстати посмотрел Ардуиновкую либу, судя по коду там все 8 прерываний можно использовать.
Я тебе предлагал, но ты как то не отреагировал, ты можешь повесить все свои сигналы на PortC и через диоды обьеденить на одном входе с настроенным прерыванием
Последний раз редактировалось Chip; 25.11.2011 в 13:00.
Почему, я в заметочку поставил. Потом просто из интереса, залез в приемник и вытащил PPM сигнал до разделения по каналам. Получилось один провод и питание.
Нет, я намертво соединяюсь и при включении ардуины, с нее питание идет через фильтр прямо на приемник, т.е нет вариантов "в воздухе" , другое дело, что после включения приемника, он инициализируется и на проводе PPM в течении 2 сек низкий уровень, потом пошли пачки импульсов.
Это не критично?
-------------------
Не в тему...
Прошу прощения, Chip, я не знаю как по имени, но наверно Вы немного преувеличиваете мои познания в программировании. Я из ваших примеров узнал про существование прерываний и экспериментировал с ними, потом самостоятельно разобрался с OCR, но сегодня добавилось EICR и некоторые прочие "вкусности".
Дайте мне немного времени и я разберусь, задавая возможно некорректные вопросы. Продолжаю разбирать скетчь.
Последний раз редактировалось Mastar; 25.11.2011 в 12:07.
Мои проекты - Катер для рыбалки
Эту тему просматривают: 3 (пользователей: 0 , гостей: 3)