Функция pulsein () с большими потерями, поскольку она представляет собой жесткий цикл и возвращает число * предполагаемых тактовых циклов, необходимых для цикла
...
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (numloops++ == maxloops)
return 0;
width++;
}
// convert the reading to microseconds. The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.
return clockCyclesToMicroseconds(width * 21 + 16);
Наиболее точный метод для определения времени ввода PIN-кода - использовать функцию ВВОДА ВВОДА. Посмотрите на этот пример . Это позволяет захватывать вход на 1x ЦП для максимального разрешения, и каждый край входного вывода захватывает значение тактового сигнала таймера для чтения из сгенерированной службы прерываний. Это также позволяет прерыванию переполнения таймера поддерживать большое абсолютное время для захвата. Так как 1х прокатит довольно быстро. Захваты сохраняют время в массив для чтения основным циклом.
Где для сигналов по ИК типичной библиотекой является библиотека shirriff / Arduino-IRremote . Там, где есть несколько демонстрационных примеров, которые будут считывать и отправлять ИК-сигнал из демодулированного сигнала. Чтобы можно было создать эскиз собственного дизайна. Этот код первоначально создает прерывание таймера, которое опрашивает входной контакт со скоростью, определяемой
#define USECPERTICK 50 // microseconds per clock interrupt tick
в файле IRremote.h. Для моих целей я изменил это до 25 нас. Где я нахожу это, все еще могут периодически отсутствовать потоки импульсов.
Обратите внимание, что демодуляция лучше всего достигается в ИК-приемнике, который, в свою очередь, выводит этот интересующий сигнал. Где добавить немного фона. Использование типичной модуляции 38 кГц соответствует минимальному разрешению 26,3 мкс на такт импульса. Библиотека Шерифа показывает, что большинство бодов или битов порядка 10+ импульсов. Которые, кажется, соответствуют вашим желаемым временам.
microtherion / Arduino-IRremote форк работы Шириффа улучшает прием, заменяя опрос прерывания таймера на выводе с использованием PinChangeInterrupts. Который я слил в свой собственный форк mpflaga / Arduino-IRremote , который добавляет несколько других функций.
Таким образом, вы можете использовать любую из вышеперечисленных библиотек. Или создайте свое собственное приложение, которое использует любой из следующих способов для захвата краев.
- опросы по событию таймера (например, 50 мс)
- захватывает micros () на PinChangeInterrupt
- использует прерывания захвата ввода, чтобы получить точное время
Вот некоторые тестовые данные
pulseIn
теста. Один Arduino послал, как предполагалось, импульсы 14us, а другой выплюнул эти данные:Как видите, импульсы отнюдь не точны. Время было бы более точным, если бы отправляющие и получающие концы были записаны в сборке или даже выгружены на их собственные процессоры.
источник