Помогите вычислить ширину импульса!
- Войдите на сайт для отправки комментариев
Пт, 17/02/2017 - 01:55
Здравствуйте!
Не могу точно вычислить ширину.
Имеется Nano, с нее подается шим сигнал на Uno в радиусе 1000-2000 мкс с шагом 1 мкс.
Требуется точное считывание вплоть до 1 шага для продвижения действий дальше.
1. Пробовал через pulsein,
плюсы: изменение по 1 шагу (1 мкс);
минусы: даже при голом коде ширина ~ (995-1985), при наличии Serial порта и его загруженности ширина резко падает, в чем причина и откуда такая зависимость я пока не понимаю, так же само значение держится нестабильно и постоянно дергается.
Код с pulsein:
int pin = 2; unsigned long duration; void setup() { pinMode(pin, INPUT); } void loop() { duration = pulseIn(pin, HIGH); }
2. Через прерывания:
плюсы: измеряется точно, почти нет помех, Serial порт не влияет, не мешает программе;
минусы: собственно главный, ради чего все и замышлялось, минимальный шаг = 4 мкс.
Код с прерыванием:
#define pin 2 volatile unsigned long ChannelIn; void setup() { pinMode(pin, INPUT); attachInterrupt(digitalPinToInterrupt(pin), calcChannel, CHANGE); } void calcChannel() { static unsigned long Start; if(digitalRead(pin)) { Start = micros(); } else { ChannelIn = (unsigned long)(micros() - Start); } } void loop() { // put your main code here, to run repeatedly: }
3. Так же нашел нечто непонятное:
int pin = 2; unsigned long duration; unsigned long v1 = 0; unsigned long v2 = 0; unsigned long itog = 0; void setup() { pinMode(pin, INPUT); } void loop() { duration = pulseIn(pin, HIGH); while (digitalRead(pin) == LOW); v1 = micros(); while (digitalRead(pin) == HIGH); v2 = micros(); itog = v2-v1; }
Собственно "itog" показывает значения как и во 2 случае с прерываниями, вроде бы просто и отлично, но опять же минимальный шаг 4 мкс все перекрывает.
Самое непонятное, что работает только с "pulsein", без него выдает ахинею.
Самое непонятное, что работает только с "pulsein", без него выдает ахинею.
Сам новичок и буду рад любой помощи.
Вы представляете что такое фронт импульса? Можете посчитать какой у вас? А посмотреть в реале? Это я к тому, что надо ставить реальные задачи. Что бы получить точность 1 микросекунду нужна схемотехника. Нужны правильные линии передачи и согласованные входные - выходные сопротивления. У вас всё это обеспечено? Если нет, то добится такой точности невозможно. С точки зрения програмирования, такую точность может обеспечить только режим захвата таймера. Не прерывание и не pulseIn.
Так я же писал, что pulsein вроде как выдает точность в 1 мкс, но по неизвестным мне причинам жестко проседает.
Фронт импульса на подъем ~0.017 мкс, на спад ~ 0.018 мкс.
Расскажите, пожалуйста, поподробнее про режим захвата, первый раз слышу.
Самое непонятное, что работает только с "pulsein", без него выдает ахинею.
Читаем букварь: "На 16MHz платах Ардуино (Duemilanove и Nano) функция micros() имеет разрешение 4 микросекунды (возвращаемое значение всегда кратно 4)."
Тут библиотека есть http://interface.khm.de/index.php/lab/interfaces-advanced/frequency-measurement-library/
http://interface.khm.de/index.php/lab/interfaces-advanced/frequency-measurement-library/
внизу страницы, скачиваем, изучаем. Удачи
Из мануала