Измерение длительности и расстояния между импульсами

Я хочу знать, как это делается (или, по крайней мере, как бы вы это сделали) для измерения длительности и расстояния между импульсами сигнала в микроконтроллере (или лучше).

Пример: у меня есть пара Arduinos и пара этих радиочастотных передатчиков/приемников (http://bit.ly/oT05Qg), и у меня есть настройка протокола, которая говорит, что я должен получать 4 бита (1111) с длительностью 0. ,5 микросекунд и интервал между ними в 1,5 микросекунды. Если это отличается, я должен игнорировать информацию.

Как я могу/вы бы это сделали?

PS: лучший пример из реальной жизни, который я смог найти, это: http://en.wikipedia.org/wiki/File:Interrogation.jpg

К вашему сведению, документация в связанном устройстве использует библиотеку Arduino под названием «VirtualWire». Простой ответ - использовать это, но я думаю, что это в любом случае хороший вопрос и возможность узнать, как использовать прерывания таймера или любое другое решение, которое публикуется здесь.

Ответы (3)

Я, конечно, не стал бы пытаться сделать это с помощью Arduino (помните, вы спросили, что я буду делать). Измерить характеристики импульсов на частоте 500 кГц будет непросто. Большой вопрос, который вы оставили открытым, заключается в том, насколько близко это должно быть, или, точнее, насколько близко к вам нужно знать, что это идеальные тайминги 500 нс и 1,5 мкс? Если вам нужно знать это с точностью до 1%, например, то это будет сложно и довольно дорого.

Если достаточно отбирать сигнал каждые 250 нс и жить с полученной неопределенностью во времени, тогда это проще, но все же сложно. В этом случае вы можете записать сигнал в регистр сдвига на частоте 4 МГц, а затем проанализировать результат в прошивке. Генерация тактового сигнала с частотой 4 МГц с помощью самых передовых микроконтроллеров проста, и многие из них будут иметь периферийное устройство SPI, которое можно переназначить в последовательно-параллельный преобразователь.

На таком процессоре, как PIC 24H, частота инструкций может достигать 40 МГц. Для обработки остается только 10 инструкций в среднем на бит, что звучит слишком мало для того, чтобы этот метод работал.

Другой подход заключается в включении счетчиков стробирования для высоких и низких значений времени и, таким образом, подсчета количества тактовых импульсов между фронтами. У вас все еще есть 1 миллион ребер в секунду, или 40 инструкций на ребро. Это все еще звучит жестко, но, возможно, выполнимо в зависимости от того, что еще вам нужно сделать и что нужно сделать с результатом. В 24H есть модули «захвата входных данных», которые делают большую часть этого аппаратно, но прошивка все еще должна понимать результирующие измерения длительности.

Обратите внимание, что ваша последовательность импульсов имеет средний уровень 1/4, который можно использовать с некоторой ловкостью и в зависимости от того, что еще происходит, как быстро вам это нужно и многого другого, о чем вы не сказали.

Теперь, не будет ли лучше, если я подниму частоту, скажем, до 1030 МГц? И отвечая на ваш вопрос: я считаю, что у меня может быть определенный запас точности, но не слишком большой. Я предполагаю, что это должно быть примерно на 95% точно по времени.

Многие схемы асинхронной последовательной связи, такие как RS232, включают в себя известное состояние простоя/метки линии и стартовый сигнал/бит, а также стоповые биты. Передискретизация линии RX позволяет синхронизироваться до середины начальных битов в середине и, наконец, производить выборку каждого бита и проверять состояние стоповых битов. http://en.wikipedia.org/wiki/Асинхронная_последовательная_коммуникация

Существует функция Arduino , специально предназначенная для измерения длины импульса:

pulseIn(pin, value)
pulseIn(pin, value, timeout) 

Однако он не подходит для ваших целей, так как диапазон обнаруживаемой длины импульса составляет от 10 микросекунд до 3 минут. Кроме того, как только измерение будет выполнено, вам придется обработать результат (по крайней мере, сохранить его где-то), что требует времени и может привести к тому, что вы пропустите начало следующего импульса.

Вы можете измерить более короткие импульсы, установив ISR на контакт с

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); 

и используя micros()функцию с разрешением 4 микросекунды, но это все, что вы можете получить. Arduino просто недостаточно быстр, чтобы измерять более короткие импульсы без специального оборудования. Наиболее перспективным было бы использование SPI, если он есть на ваших платах, но он будет работать только в том случае, если вы получаете импульсы группами, которые можно сопоставить с транзакциями SPI.